title: Webpack 5 Upgrade Guide
date: 2020-11-5 20:05:50
tags:
- Webpack
Webpack 5 has recently been released, bringing many optimizations and new features. The build efficiency of front-end projects will be greatly improved. Moreover, compared to Webpack 4, the upgrade to v5 is smoother and does not involve many breaking changes.
Webpack 5 has recently been released, bringing many optimizations and new features. The build efficiency of front-end projects will be greatly improved. Moreover, compared to Webpack 4, the upgrade to v5 is smoother and does not involve many breaking changes.
The overall development direction of this major release is as follows:
- Attempt to improve build performance with persistent caching.
- Attempt to improve long-term caching with better algorithms and defaults.
- Attempt to improve bundle size with better Tree Shaking and code generation.
- Attempt to improve compatibility with web platforms.
- Attempt to clean up internal structures that were in a strange state during the implementation of v4 features.
- Attempt to prepare for future features by introducing groundbreaking changes now.
- Aim to stay on version v5 for as long as possible.
To try out the changes brought by the new features, I have upgraded some of my open-source projects. This article summarizes some of the issues I encountered during the upgrade process.
Upgrading Dependencies with npm-check-updates#
The npm-check-updates plugin automatically checks for the latest versions in the package.json file and performs batch upgrades.
npm install -g npm-check-updates
ncu
The ncu command automatically checks for the latest versions of dependencies in the package.json file and lists the upgradable dependencies.
ncu -u
Running this command updates the dependency versions in the package.json file to the latest versions.
Then, run yarn or npm install to install the latest versions.
Typescript Types#
Webpack 4 used @types/webpack for type checking. Webpack 5 generates TypeScript type files from the source code.
Modification:
yarn remove @types/webpack
webpack-cli#
For starting projects and building in webpack 4.x, the following commands were used:
"scripts": {
"start": "webpack-dev-server --config ./config/webpack.config.dev.ts --progress --colors",
"build": "webpack-cli --config ./config/webpack.config.prod.ts --progress --colors"
},
Running npm start resulted in the following error:
Error: Cannot find module 'webpack-cli/bin/config-yargs'
Corresponding issue: https://github.com/webpack/webpack-dev-server/issues/2424
In v5, use webpack-cli/serve instead of webpack-dev-server for the start command:
The corresponding script modification:
"scripts": {
"start": "webpack-cli serve --config ./config/webpack.config.dev.ts",
"build": "webpack-cli --config ./config/webpack.config.prod.ts --progress --colors"
},
Command Line Arguments#
webpack-cli removed and added some command line arguments in the webpack 5 version, resulting in the following error at runtime:
--colors
[webpack-cli] Unknown argument: --colors
The above error indicates that the --colors parameter is not supported in v5 and needs to be removed.
Refer to the official GitHub repository for the supported parameters in different versions: https://github.com/webpack/webpack-cli/tree/next/packages/webpack-cli#webpack-5
webpack loader#
Setting loader options using query parameters will result in an error when starting webpack:
[webpack-cli] Promise rejection: Error: Compiling RuleSet failed: Query arguments on 'loader' has been removed in favor of the 'options' property (at ruleSet[1].rules[5].loader: file-loader?name=images/[name].[hash:5].[ext])
[webpack-cli] Error: Compiling RuleSet failed: Query arguments on 'loader' has been removed in favor of the 'options' property (at ruleSet[1].rules[5].loader: file-loader?name=images/[name].[hash:5].[ext])
{
test: /\.(png|jpg|jpeg|gif|svg)$/,
loader: "file-loader",
//loader: "file-loader?name=images/[name].[hash:5].[ext]",
options: {
name: 'images/[name].[hash:5].[ext]',
},
}
devtool#
[webpack-cli] Invalid configuration object. Webpack has been initialized using a configuration object that does not match the API schema.
- configuration.devtool should match pattern "^(inline-|hidden-|eval-)?(nosources-)?(cheap-(module-)?)?source-map$".
BREAKING CHANGE since webpack 5: The devtool option is more strict.
Please strictly follow the order of the keywords in the pattern.
Removing Node.js Module Polyfills#
Webpack 4 and earlier versions included polyfills for some Node.js modules such as crypto, buffer, and process. If your project uses these modules, the corresponding polyfills were automatically applied. In v5, these polyfills have been removed, and if you need to use them, you need to manually add them to the configuration file:
plugins: [
new ProvidePlugin({
Buffer: ["buffer", "Buffer"],
process: "process",
}),
]
Using eslint-webpack-plugin instead of eslint-loader#
The eslint-webpack-plugin solves some issues with eslint-loader. It provides better configuration options, generates reports, and directly uses caching from eslint, only linting modified files.
Overall, eslint-webpack-plugin is more convenient to use and significantly improves initial startup speed.
Modification:
yarn add eslint-webpack-plugin -D
const ESLintPlugin = require('eslint-webpack-plugin');
module.exports = {
// ...
plugins: [new ESLintPlugin({
fix: true,
lintDirtyModulesOnly: true,
})],
// ...
};
babel-polyfill#
Before Babel > 7.4.0, we usually installed babel-polyfill or @babel/polyfill to handle instance methods and newly added built-in functions in ES+. Starting from Babel 7.4.0, it is not recommended to use these packages anymore. Instead, import core-js/stable (to polyfill ECMAScript features) and regenerator-runtime/runtime (for generator functions that require transpilation) directly:
import "core-js/stable";
import "regenerator-runtime/runtime";
Below is an example using transform-runtime:
Install dependencies:
yarn add babel-loader @babel/core @babel/preset-env @babel/plugin-transform-runtime -D
yarn add @babel/runtime-corejs3
.babelrc configuration file:
{
"presets": [
[
"@babel/preset-env",
{
"modules": false,
}
]
],
"plugins": [
[
"@babel/plugin-transform-runtime",
{
"corejs": {
"version": 3,
"proposals": true
},
"useESModules": true
}
]
]
}
Reference: https://segmentfault.com/a/1190000020237817
Reference: https://webpack.js.org/blog/2020-10-10-webpack-5-release/