You've mixed different approaches how to include legacy vendor modules. This is how I'd tackle it:
1. Prefer unminified CommonJS/AMD over dist
Most modules link the
dist
version in the
main
field of their
package.json
. While this is useful for most developers, for webpack it is better to alias the
src
version because this way webpack is able to optimize dependencies better (e.g. when using the
DedupePlugin
).
// webpack.config.js
module.exports = {
...
resolve: {
alias: {
jquery: "jquery/src/jquery"
}
}
};
However, in most cases the dist
version works just fine as well.
2. Use the ProvidePlugin
to inject implicit globals
Most legacy modules rely on the presence of specific globals, like jQuery plugins do on $
or jQuery
. In this scenario you can configure webpack, to prepend var $ = require("jquery")
everytime it encounters the global $
identifier.
var webpack = require("webpack");
...
plugins: [
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery"
})
]
3. Use the imports-loader to configure this
Some legacy modules rely on
this
being the
window
object. This becomes a problem when the module is executed in a CommonJS context where
this
equals
module.exports
. In this case you can override
this
with the
imports-loader.
Run npm i imports-loader --save-dev
and then
module: {
loaders: [
{
test: /[\/\\]node_modules[\/\\]some-module[\/\\]index\.js$/,
loader: "imports?this=>window"
}
]
}
The imports-loader can also be used to manually inject variables of all kinds. But most of the time the ProvidePlugin
is more useful when it comes to implicit globals.
There are modules that support different module styles, like AMD, CommonJS and legacy. However, most of the time they first check for define
and then use some quirky code to export properties. In these cases, it could help to force the CommonJS path by setting define = false
.
module: {
loaders: [
{
test: /[\/\\]node_modules[\/\\]some-module[\/\\]index\.js$/,
loader: "imports?define=>false"
}
]
}
5. Use the script-loader to globally import scripts
If you don't care about global variables and just want legacy scripts to work, you can also use the script-loader. It executes the module in a global context, just as if you had included them via the
tag.
6. Use noParse
to include large dists
When there is no AMD/CommonJS version of the module and you want to include the dist
, you can flag this module as noParse
. Then webpack will just include the module without parsing it, which can be used to improve the build time. This means that any feature requiring the AST, like the ProvidePlugin
, will not work.
module: {
noParse: [
/[\/\\]node_modules[\/\\]angular[\/\\]angular\.js$/
]
}
沒有留言:
張貼留言
留個話吧:)