Migrating from webpack 3 to 4
After hearing lots of stories about the large performance improvements of the webpack 4 beta, when the final release came out, I was eager to migrate our project from v3.
webpack’s configuration can be difficult to understand anyway, and unfortunately, the webpack team was trying to hit a deadline and was unable to write any migration documentation before the v4 release. Lucky for you, we decided to push through anyway, and we took notes!
For more info about the release, check out:
- The webpack 4 announcement post on Medium
- The v4.0.0 tag release notes on GitHub
Upgrade node to 8.9.4
To get the best performance out of v4, @wSokra says use at least node 8.9.4.
Upgrade webpack
webpack’s core functionality and CLI code have been split into two repos now:
$ npm i -D webpack webpack-cli
Use a mode
You may see an error like: The 'mode' option has not been set. Set 'mode' option to 'development' or 'production' to enable defaults for this environment.
In v4, you have to set a mode in your config:
{
mode: "production",
}
It can also be set when invoked from CLI:
$ webpack --mode production
Change CommonsChunkPlugin to splitChunks
You may see an error like: Error: webpack.optimize.CommonsChunkPlugin has been removed, please use config.optimization.splitChunks instead.
The CommonsChunkPlugin is an opt-in feature that creates a separate file (known as a chunk), consisting of common modules shared between multiple entry points.
This functionality has moved from the CommonsChunkPlugin to the
optimization.splitChunks
setting.
Previously in v3, we used runtime and vendor chunks like so:
{
plugins: [
new webpack.optimize.CommonsChunkPlugin({
name: ["runtime"],
minChunks: Infinity,
}),
new webpack.optimize.CommonsChunkPlugin({
name: "vendor",
minChunks: ({ resource }) => /node_modules/.test(resource),
}),
];
}
In v4, this roughly translates to:
{
optimization: {
runtimeChunk: "single", // enable "runtime" chunk
splitChunks: {
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name: "vendor",
chunks: "all"
}
}
}
}
}
More information about the new optimization.splitChunks
option can be found
here.
Get rid of ModuleConcatenationPlugin
Also known as "scope hoisting". It is now on by default in production mode.
Change UglifyJsPlugin
You may see an error like: Error: webpack.optimize.UglifyJsPlugin has been removed, please use config.optimization.minimize instead.
v4 now handles dead code elimination internally. Both it and minimization are on by default in production mode, but to continue tuning Uglify settings, add uglifyjs-webpack-plugin:
$ npm i -D uglifyjs-webpack-plugin
And in the optimization.minimizer
section:
const UglifyJsPlugin = require("uglifyjs-webpack-plugin");
{
optimization: {
minimizer: [
new UglifyJSPlugin({
sourceMap: true,
uglifyOptions: {
…
}
})
]
}
}
Upgrade loaders
You may see an error like: Module build failed: TypeError: Cannot read property 'eslint' of undefined
This happened for us with eslint-loader and file-loader. Just upgrade the loaders:
$ npm i -D eslint-loader file-loader