I'm a little confused on the various ways webpack allows to expose a variable that isn't available on npm or to be put in the bundle. I was able to expose the google visualizations chart script's global google var by using
resolve: {
extensions: ['.js', '.json'],
alias: {
'google': path.resolve(__dirname, 'vendor', 'google.js')
}
}
combined with
plugins: [
new webpack.ProvidePlugin({
'google': 'google'
})
]
however looking at the webpack docs there a couple other ways to shim, which look like they might do something similar. There is imports-loader and exports-loader, and script-loader. I know that I've linked to the docs, but I still find their descriptions of when these four should be used a bit unclear.
Also looking at this example, is this require not assigned to a variable? Where is it meant to go? And where is the documentation on what is going on with this syntax?
require("imports?$=jquery!./file.js")
The webpack compiler can understand modules written as ES2015 modules, CommonJS or AMD. However, some third party libraries may expect global dependencies (e.g. $ for jQuery ). The libraries might also create globals which need to be exported.
scripts-loaderI never used this myself, but the idea is simple I guess. I think it can be used if for some reason you want to inject a script or a function or something in one of the modules/files you have no control over them.
imports-loader & exports-loader
In one of the apps I worked on we had to use tinymce which in its older versions was dependent on this being always window because it was built to work as a global script. Not as a CommonJS or ES module.
So in order to fix that, we had to use the import-loader so it can inject window to the script. Here how it looked like in webpack.config.js
{ test: require.resolve('tinymce/tinymce'), use: ['imports?this=>window', 'exports?tinymce'] }
Which says inject window in place of this & also we are using exports-loader here so we can export the global tinymce as a default export named tinymce so we can use it as a normal module in our app.
Thankfully all of this is already fixed in the latest releases.
ProvidePluginIn my experience, this is useful when a library is depending on another library being in a global scope or something. Like jQuery plugins for example, they do use one of these $, window.$, jQuery & window.jQuery
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
'window.$': 'jquery',
'window.jQuery': 'jquery',
}),
So what this plugin will do is to make sure when webpack sees one of these variations it will provide the jQuery object to it instead.
The difference between this & imports-loader for example that you might not know which variation is used by which script. So you let webpack handle this while the imports-loader is kind of more specific.
I hope this helped you a bit to understand the differences between all of them, also this is the new documentation page which I think better than the one you were checking https://webpack.js.org/guides/shimming/
imports and exports loaders are very simple to understand. If you use one of them, or both, your module is wrapped into another function with exports and imports.
For example, I'm using paho-mqtt module meant to be used like global <script src=""> on the page:
import Paho from 'imports-loader?this=>window!exports-loader?Paho!paho-mqtt';
//and this is transformed by webpack to something like:
(function(window){
//wow you can use `window here`, `this` in the global context === window.
// original module code here
// that exposes global var `Paho`
module.exports = Paho;
})(this);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With