This is a year-long summary of webpack5 upgrade practice. I started this project in April 2020 when webpack5 was in
beta phase, and then I made a few more attempts, all of which were stuck in different branches due to compatibility between self-published and third-party plugins.
2020-10: email@example.com Release
2021-01 to 04: WEB New project, webpack5, React17…
The following is a record of the practice related to the upgrade after it was finally completed in the project.
Upgrade of webpack and dependency versions
Install the latest version of webpack.
Plugin Dependency Upgrade: Update the relevant plugins used in the project to their latest versions on demand. There may be various compatibility issues in this process, which need to be analyzed and solved according to the actual situation.
Upgrade dependency versions with npm-check-updates
160+ Third-party dependencies, how to quickly confirm the latest version and whether it needs to be upgraded?
npm updateare too simple and brutal
- Manual update: In Microsoft Visual Code editor, when you hover over a dependency line and hold it, it will look up the latest version of that dependency line.
- Helper tool:
Install and use
Example usage of the
Project Upgrade Practice.
Writing webpack configuration with TypeScript
It is recommended to use TypeScript to write webpack configuration files. With TypeScript’s type detection, you can quickly determine which property configurations are valid, no longer valid, or incorrect. Example.
Of course, for js-formatted configuration files, you can also add
@ts-check to the top of the configuration file to enable TS type checking capability for js files. Example.
webpack build configuration updates and compatibility
- Coding quality and efficiency
- ESLint upgrade
huskyupgrades: git hook performance is greatly improved in large projects
- Public modules, ESLint / TS Check related
Shortcutcoding TS refactoring
webpackconfiguration and related dependency plugins
- Custom plugin updates and development:
html-webpack-plugin: API changes, custom logic debugging analysis and compatibility updates that depend on its API
css-loaderand cssModule changes
CopyWebpackPluginusage changes, parameter configuration changes
webpack.IgnorePluginparameter configuration changes
- DLL-related configuration
- Custom plugin updates and development:
- Remove the
webpackplugin that is no longer used
script-ext-html-webpack-plugin: Support for feature requests in the latest version of the
cache-loader: change to use webpack5’s built-in caching and multithreading configuration, etc.
- Business dependency plugin compatibility
- Huge impact, may lead to unpredictable accidents: minimal changes, confirmed by the business caller on an application-by-application basis
Compatibility details are the most complex and the problem is quite time-consuming to analyze, which is the main reason why it is difficult to upgrade smoothly. Heavy reliance on third-party libraries can deepen the complexity of project upgrades.
Compatibility of webpack plugins
Generally speaking three-party plugin compatibility is the main issue with upgrading
webpack5. Early on, the degree of compatibility follow up varied across plugins, and there were quite a few details of odd performance issues.
webpack API changes, requiring development of plugin-compatible versions.Because some APIs were changed or deprecated, many plugins needed to be partially rewritten for compatibility.
Self-coded plugin compatibility.Basically all webpack plugins that are self-coded for specific needs need to be interface-level compatible, which increases the development and debugging effort significantly.
Large differences between old and new versions of three-way plugins.Some plugins may have large changes in the default parameter behavior in new versions, which can also lead to a variety of strange problems, debugging is more complex, and requires careful step-by-step analysis. For example, the problem of
css-loaderchanging the default handling of
css-loader 与 cssModule
options.modules parameter needs to be configured to keep the logic consistent with previous versions of
Changes to esModules default rules (standard ESM).
output err error problem
Deprecated file-loader and url-loader
DEPRECATED for v5: please consider migrating to asset modules.
raw-loader: to import a file as a string
file-loader: handle file dependencies loaded by
url-loader: relies on
file-loader, contains all its capabilities, and can convert files to
Resource processing in webpack5 asset modules:
asset/source: exports the source code of the asset. Previously achievable by using
asset/resource: emits a separate file and exports the URL. Previously achievable by using
asset/inline: exports a data URI of the asset. Previously achievable by using
asset: automatically chooses between exporting a data URI and emitting a separate file. Previously achievable by using
url-loaderwith asset size limit.
Using url-loader in webpack5
If the url-loader dependency of an old project is difficult to modify and remove, there is still a corresponding configuration that can be implemented
asset modules configuration and usage examples
If possible, using asset modules directly is the best way to be future-proof.
About sass: node-sass and dart-sass
sass: css extension language
node-sass: C++ module with system platform and Node.js version dependency
- Pros: high performance, fast compilation speed
- Disadvantages: installation failure due to high platform dependency
dartwritten and compiled as
- Pros: cross-platform, less problems with installation, etc., has become the main official choice
sass-loaderhas changed the default interpreter to
Can I switch directly to
Business code compatibility updates are cumbersome and require extensive regression testing.
Building Performance Efficiency: Persistent Caching and Multithreading
The most time consuming part of the webpack build process is the compilation of the various source files. The main ideas to improve build efficiency are multi-threaded parallelism and avoid duplicate compilation (caching of compilation results).
Build performance optimization for webpack4 and earlier
Long-term development and maintenance of large projects often take tens to hundreds of seconds to build.
Before webpack4, plugins like
cache-loader, etc. were almost standard for project builds in order to use caching to improve build efficiency, but even then it was often unsatisfactory, as these third-party plugins could not work together perfectly and integrate into all parts of the build process.
- cache-loader: cache build results to
node_modules/.cache-loaderdirectory (you can specify the location)
- Enable the
cacheDirectory: true, similar to
- hard-source-webpack-plugin: cache build results to the
node_modules/.cache/hard-sourcedirectory (you can specify the location)
- thread-loader: execute the
loaderbuild process using multiple threads
- happypack : An early multi-threaded solution implemented by a third party, not updated since the official
webpack dll: Pre-compiled resources that are not frequently modified
cache configuration in webpack5
In webpack5, the cache configuration is implemented through the cache field, and it performs better.
Comparison of webpack5 caching effects
webpack5 first build.
webpack5 secondary build (with caching).
Comparison of webpack4 caching effects
webpack4 first build (with thread-loader).
webpack4 secondary build (with caching).
Go further: thread-loader and esbuild-loader
thread-loader still has its place. While
parallelism simply specifies the number of threads for parallel builds,
thread-loader allows for separate multi-threaded build testing and optimization for special loader classes such as
In addition, using
esbuild-loader instead of
babel-loader to achieve compilation acceleration is also an option to speed up build efficiency. The pros and cons lie in the dependency of the build output and development experience on their respective ecologies, where the difference in hot update is a big contrast in the development experience.
webpack5 first build (thread-loader).
Efficiency of next generation build tool solutions
The development experience is undoubtedly quite comfortable for next-generation front-end build solutions like vite and snowpack with no Bundles. Thanks to the no-build, compile-on-demand feature, projects can be launched in seconds, no matter how large they are.
However, from simple tests and community feedback, there are many details that are difficult to handle perfectly when dealing with complex and personalized requirements. webpack has a long way to go.
A brief overview of other configuration updates for webpack5
Optimization is an important configuration property that has changed significantly in webpack5. Some optimization features that used to be enabled using the built-in plugins have been turned on or off as configuration items here. See here for details.
node environment compatibility
Previously, the goal of
webpack was to build applications that could run browser-side, so there was default compatibility support for some variables that were only available in the
Node.js environment. In
webpack5, these compatibility handles are no longer supported by default. Now the
node property can only be configured with a single
global property, and all other compatibility is achieved through
resolve.fallback itself. For example, for compatibility with
nodejs native modules such as
A value of
false means that nothing is done, which is basically similar to the effect of
dll filtering in
Buffer also requires the
Warning message for deprecating APIs
For some deprecating APIs, webpack5 wraps them with util.deprecate. It makes these APIs print a warning message on the command line when they are called.
During the upgrade to webpack5, you should set
process.traceDeprecation=true or add the command line argument
-trace-deprecation to debug to see where API calls are deprecated and try to update or use the latest version of the plugin in question.
If the latest versions of some plugins you must use also do not handle such API calls yet, you can set
-process.noDeprecation=true to turn it off:
webpack5defaults some common configurations, such as
- If you are using
Yarn PnPand have
pnp-resolver-pluginconfigured, then you can remove the relevant configuration, which is now built-in.
You can start by referring to the official
webpack4 -> webpack5 migration guide at
Next generation build tool?
The main popular build tools currently available are.
- Parcel Extreme zero-configuration web application packaging tool
- Snowpack The faster frontend build tool.
- vite The next generation frontend development and build tool
- esbuild Written in
Goand mainly used for build acceleration
The core idea of
vite, currently known as the next generation of build tools, is based on the ES20200 specification’s
ES Modules native support, where the build process essentially compiles the source code into the
ES Module specification format and directly references it in the browser.
- No bundles, true compile-on-demand, load-on-demand
- Extremely fast cold start
- Extremely fast hot updates
- Significantly improved development efficiency and experience
- Compatibility, compile result differences: migration of old projects is risky
- Some feature usage/syntax not easy to convert support
- Not enough richness of plug-in support
- Cost of self-coded plug-in development