I am reading Shimming from the official docs. of Webpack, but still I'm unable to get what it means ?
As I am new to Webpack, I have also tried to do some RND, but I could not get the proper answer from that. I have few questions about Shimming which are as follow :
What is Shimming ?
What does Shimming does actually ?
Why there is need of Shimming in webpack ?
How it works ?
Pros and cons of Shimming.
If anyone knows, even few answers of the questions mentioned above, please let me know.
Some libraries depend on global variables. For example, a jQuery plugin may expect the "$" global variable to be available.
Without shimming that variable with ProvidePlugin you would get an error $ is not defined.
In simple terms shimming would replace all global $ variables in JavaScript modules with require('jquery'). In some legacy libraries you would also need to shim jQuery or window.$ because the plugin only performs a basic text replacement.
You only need shimming for libraries or any code you do not have control over. In the application modules you should import jQuery with import $ from 'jquery' and avoid global variables.
Related
I'm trying to use external libs in tests. I added all needed links in karma.conf.js and some libs were included without any problem. But for some libs karma sets "undefined" instead of "this" when compiling they, like this:
And of course, then I have errors because of it:
What could I do wrong? Is it possible to include such lib?
In a JavaScript module, this is undefined at the top level (i.e., outside functions). Because of that, Rollup will rewrite any this references to undefined so that the resulting behaviour matches what will happen when modules are natively supported.
To solve it you can use options.context and options.moduleContext to change this behaviour. Like this: context: 'window'
module.exports = {
root: true,
parser: '#typescript-eslint/parser',
plugins: ['#typescript-eslint'],
extends: [
'eslint:recommended',
'plugin:#typescript-eslint/recommended',
],
};
Whenever I add or remove this line: plugins: ['#typescript-eslint']
eslint seems to behave the same. What exactly plugins property does and when using it is required?
This question is pretty straight forward if you think about what a plugin is.
The docs don't really do a good job of just out-right saying what an ESLint plugin is, though if you read through the docs (https://eslint.org/docs/user-guide/configuring), then it's pretty trivial to figure out:
ESLint supports the use of third-party plugins
When using rules, environments or configs defined by plugins. Before using the plugin, you have to install it using npm.
So a plugin is a 3rd party module that can define rules, environments, or configs.
So to answer your question:
What exactly plugins property does [sic]
the plugins property tells ESLint what plugins you want to use
and when using it is required? [sic]
when you use something from a plugin, you must first tell ESLint about it with the plugins property.
Plugins seem to work anyway when this field is omitted
If you use the extends option with the syntax plugin:<plugin>/<config>, then ESLint will load a specific file from the plugin ahead of time.
Why? Because this allows a plugin to provide a config and reduce the amount of config you need. A plugin's config can provide the plugins option for you, meaning you don't need to do it yourself.
I was also curious about what is parser and plugin
From documentation
"For example, once this parser successfully produces an AST for the TypeScript source code, it might well contain some information which simply does not exist in a standard JavaScript context, such as the data for a TypeScript-specific construct, like an interface.
The core rules built into ESLint, such as indent have no knowledge of such constructs, so it is impossible to expect them to work out of the box with them.
Instead, you also need to make use of one more plugins which will add or extend rules with TypeScript-specific features."
This helped me to understand it better.
In an Ember app, when using certain dependencies like moment installed via bower, we have to also import the same in the ember-cli-build.js file:
app.import('bower_components/moment/moment.js');
My question is why is that needed, since I would assume everything inside node_modules as well as bower_components should be available for use inside the app.
Also if that is not the case, how do we identify which dependencies would require such explicit import to be able to use them ?
You don't have to, actually.
There is a package now that lets you 'just import' things: https://github.com/ef4/ember-auto-import
Some reading on the topic of importing: https://discuss.emberjs.com/t/readers-questions-how-far-are-we-from-being-able-to-just-use-any-npm-package-via-the-import-statement/14462?u=nullvoxpopuli
In in-depth answer to your question and the reasons behind why things are the way they are is posted here:
https://discuss.emberjs.com/t/readers-questions-why-does-ember-use-broccoli-and-how-is-it-different-from-webpack-rollup-parcel/15384?u=nullvoxpopuli
(A bit too long for stack overflow, also on mobile, and I wouldn't want to lose all the links and references in a copy-paste)
Hope this helps
Edit:
To answer:
I just wanted to understand "in what cases" do we need to use the import statement in our ember-cli-build (meaning we do not do import for all the dependencies we have in our package/bower.json)...But only for specific ones...I wanted to know what is the criteria or use case for doing import.
Generally, for every package, hence the appeal of the auto-import and / or packagers (where webpack may be used instead of rollup in the future).
Though, it's common for ember-addons to define their own app.import so that you don't need to configure it, like any of these shims, specifically, here is how the c3 charting library is shimmed: https://github.com/mike-north/ember-c3-shim/blob/master/index.js#L7
Importing everything 'manually' like this is a bit of a nuisance, but it is, in part, due to the fact that js packages do not have a consistent distribution format. There is umd, amd, cjs, es6, etc.
with the rollup and broccoli combo, we need to manually specify which format a file is. There are some big advantages to the rollup + broccoli approach, which can be demonstrated here
and here
Sometimes, depending on the transform, you'll need a "vendor-shim".
These are handy when a module has decided it wants to be available on the window / global object instead of available as a module export.
Link: https://simplabs.com/blog/2017/02/13/npm-libs-in-ember-cli.html
(self represents window/global)
however, webpack has already done the work of figuring out how to detect what format a js file is in, and abstracts all of that away from you. webpack is what ember-auto-import uses, and is what allows you to simply
import { stuff} from 'package-name';. The downside to webpack is that you can't pipeline your transforms (which most people may not need, but it can be handy if you're doing Typescript -> Babel -> es5).
Actually: (almost) everything!
Ember does, by default, not add anything to your app except ember addons. There are however some addons that dynamically add stuff to your app like ember-browserify or ember-auto-import.
Also just because you do app.import this does not mean you can use the code with import ... from 'my-package'. The one thing app.import does is it adds the specified file to your vendor.js file. Noting else.
How you use this dependency depends completely on the provided JS file! Ember uses loader.js, an AMD module loader. So if the JS file you app.imported uses AMD (or UMD) this will work and you can import Foo from 'my-package'. (Because this is actually transpiled to AMD imports)
If the provided JS file provides a global you can just use the global.
However there is also the concept of vendor-shims.. Thats basically just a tiny AMD module you can write to export the global as AMD module.
However there are a lot of ember addons that add stuff to your app. For example things like ember-cli-moment-shim just exist to automagically add a dependency to your project. However how it's done completely depends on the addon.
So the rule is:
If its an ember addon read the addon docs but usually you shouldn't app.import
In every other case you manually need to use the library either by app.import or manual broccoli transforms.
The only exception is if you use an addon that tries to generically add dependencies to your project like ember-browserify or ember-auto-import
Has anyone used mockjax for jasmine unit tests with webpack? I keep getting $.mockjax is undefined. It has something to do with
// NOTE: To use Mockjax as a Node module you MUST provide the factory with // a valid version of jQuery and a window object (the global scope): // var mockjax = require('jquery.mockjax')(jQuery, window);
but I can't use require in an AMD module. I've attempted to use a shim and the import-loader with webpack but I may have done something wrong because I don't fully understand the problem.
This is pretty old, but I missed it because of the lack of the mockjax tag! Anyway, this should have been resolved in PR #284. There was an issue about this with some suggestions, specifically:
{
test: require.resolve('jquery-mockjax/dist/jquery.mockjax.js'),
use: ['imports-loader?this=>window,exports=>""']
}
So I have a nice chunk of code that is the same across many different javascript files, but I occasionally have to update it due to path changes or other various conditions. Now copy and pasting it all over to the new files works fine but is annoying to execute. Is there a good way to maintain one javascript file with my "plugin" code and have it be accessible by other javascript files that use the plugin?
I am looking for both a good nodejs solution, and vanilla js solution. If they could be mutually shared that'd be ideal, but not required by any means. Ideally, I'd like to host my workspace in workspace/ and have some folders, workspace/front-end-js/ and workspace/back-end-nodejs/, be able to run code off a plugin in workspace/plugins/ so that I can execute things like MyPluginVar.Foo();
I am aware of some systems, like the node's var foo = require('bar'); and the frontend browserified version, but really do not know all my options. What's the best way of writing and organizing javascript plugins?
--
Edit: I'm really trying to avoid npm, but it might be the best option.
You typically add your shared libraries and plugins as dependencies to your project's package.json file and install them using npm.
CommonJS modules, which use the module.exports object and require function, are the de facto standard at the moment.
ES2015 modules, which use the export and import statements, are an emerging formal standard, but support for them is not yet universal. They are a good option if your environment supports them.
To load either type of module on the front end, you will need to use a bundler such as Webpack or Browserify.
Older javascript modules typically publish to the global scope (window), and are a simple option for front end code.
You can also support multiple module systems if you like by using a UMD (Universal Module Definition) wrapper. Here's an example from the UMD Github repo that leverages CommonJS if supported, while falling back to a browser global:
(function (root, factory) {
if (typeof exports === 'object' && typeof exports.nodeName !== 'string') {
// CommonJS
factory(exports, require('b'));
} else {
// Browser globals
factory((root.commonJsStrictGlobal = {}), root.b);
}
}(this, function (exports, b) {
// b represents some dependency
// attach properties to the exports object to define
// the exported module properties.
exports.action = function () {};
}));