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-loader
I 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.
ProvidePlugin
In 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