When you have a dependency that has dependencies on global variables (like jQuery or lodash) or assumes that
this is bound to
window, you can use the imports-loader to provide those dependencies explicitly.
Here we have a module that depends on Lodash to add a couple mix ins to be used later in the application. We're loading this module in our app.js file, and if we go ahead and run npmstart to start up our server, we're going to get an error. We're going to see "Underscore is not defined," and that's because this module's not requiring Lodash.
Now that would be really easy to fix if we had control over this module. If it's not a dependency, or something, we can just say, "Import Lodash from Lodash," then we save that, and everything works just fine.
But, let's assume for a moment that this suite Lodash mix ins module is not ours, and it's one of our dependencies. How can we expose Lodash to this module without just sticking it on the window?
We can do this a imports loader. Let's go ahead and install that as a dev dependency, and then in our app.js file, we're going to use web packs enhanced import to expose the Lodash module to the suite Lodash mix ins module.
We'll specify the imports loader, and here we'll just add an ES link, disable lines, so we don't get that red underline there, and then we'll add a query string where this underscore variable will be assigned to the Lodash module.
We'll save that, we'll run npmstart again, and if we refresh our browser everything seems to work just fine.
Let's go ahead and open up, in the sources, those suite Lodash mix ins, to see what actually happened. Here we have this comment, "Import from imports loader," and it adds this, "require for the Lodash module," then it's within scope, so we could call this whatever we want, whatever, whenever, and if we refresh we're going to see it's going to be called whatever.
That's the syntax for this loader, for the query string, and we're off to the races, we're great. However, I don't like having this special syntax inside of my import statements, so we're going to take this, and move it to our web pack config. Let's go ahead and do that now.
We'll just cut this right here, and we'll go to our web pack config, and we're simply going to add another loader, where the test will be simply require.resolve, so we'll resolve this module, and we're just going to resolve directly to the specific module we want this loader to apply to, so source, JS, non node modules, suite Lodash mix ins, and then we'll specify our loader is exactly what we had before.
Then if we save that, and we'll restart web pack dev server, we go back to our application, and refresh, and everything is working just fine.
In review, all that you need to do to expose a variable to another module that you don't have any control over is by simply installing the imports loader, and then the web pack config.
We specify a new loader in this array of loaders, where the test is simply using require resolve to reference the specific module that we're trying to apply this loader to, and then we specify the loader as the imports loader, with the query string of the variable, and the module that we're going to be exporting from.
This query string is pretty powerful, and you can check that out to assigned window, to this, and all kinds of different things, to expose different things to modules that you have no control over, and that's how you use the imports loader.