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-04
: webpack5@5.0.0-beta.15+2020-07
: webpack5@5.0.0-beta.21+2020-10
: webpack5@5.0.0 Release2021-01 to 04
: WEB New project, webpack5, React17…2021-07
: webpack@5.4x
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
Question: 160+
Third-party dependencies, how to quickly confirm the latest version and whether it needs to be upgraded?
Options.
npm outdated
andnpm update
are 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:
npm-check-updates
Install and use npm-check-updates
:
Example usage of the npm-check-updates
command.
|
|
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.
Start webpack.
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
husky
upgrades: git hook performance is greatly improved in large projects- Public modules, ESLint / TS Check related
combokeys
->Shortcut
coding TS refactoring- More…
webpack
configuration and related dependency plugins- Custom plugin updates and development:
BuilderManager
,Benchmark
,PluginsBuilder
,caseSensitiveSassLoader
, etc. html-webpack-plugin
: API changes, custom logic debugging analysis and compatibility updates that depend on its APIcss-loader
and cssModule changesCopyWebpackPlugin
usage changes, parameter configuration changeswebpack.IgnorePlugin
parameter configuration changes- DLL-related configuration
- More…
- Custom plugin updates and development:
- Remove the
webpack
plugin that is no longer usedscript-ext-html-webpack-plugin
: Support for feature requests in the latest version of thehtml-webpack-plugin
pluginthread-loader
,cache-loader
: change to use webpack5’s built-in caching and multithreading configuration, etc.file-loader
,url-loader
- More…
- 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 ofcss-loader
changing the default handling ofcssModule
.
css-loader 与 cssModule
The options.modules
parameter needs to be configured to keep the logic consistent with previous versions of css-loader@2
.
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 stringfile-loader
: handle file dependencies loaded byimport/require
etc.url-loader
: relies onfile-loader
, contains all its capabilities, and can convert files tobase64
Resource processing in webpack5 asset modules:
asset/source
: exports the source code of the asset. Previously achievable by usingraw-loader
.asset/resource
: emits a separate file and exports the URL. Previously achievable by usingfile-loader
.asset/inline
: exports a data URI of the asset. Previously achievable by usingurl-loader
.asset
: automatically chooses between exporting a data URI and emitting a separate file. Previously achievable by usingurl-loader
with 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 languagenode-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
dart-sass
:dart
written and compiled aswasm
module- Pros: cross-platform, less problems with installation, etc., has become the main official choice
sass-loader
has changed the default interpreter todart-sass
Can I switch directly to dart-sass
now?
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 happypack
, hard-source-webpack-plugin
, thread-loader
, 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-loader
directory (you can specify the location) - Enable the
babel-loader
configuration item:cacheDirectory: true
, similar tocache-loader
- hard-source-webpack-plugin: cache build results to the
node_modules/.cache/hard-source
directory (you can specify the location) - thread-loader: execute the
loader
build process using multiple threads - happypack : An early multi-threaded solution implemented by a third party, not updated since the official
thread-loader
was released. webpack dll
: Pre-compiled resources that are not frequently modified- more…
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
In webpack5
, the 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 ts-loader
.
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
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.
https://github.com/webpack/changelog-v5/blob/master/MIGRATION%20GUIDE.md#update-outdated-options
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 fs
, path
, buffer
, etc.
|
|
A value of false
means that nothing is done, which is basically similar to the effect of dll
filtering in externals
.
Compatibility with Buffer
also requires the ProvidePlugin
plug-in.
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: -process.noDeprecation=true
.
Other
webpack5
defaults some common configurations, such asentry: 'src/index.js'
- If you are using
Yarn PnP
and havepnp-resolver-plugin
configured, 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
https://github.com/webpack/changelog-v5/blob/master/MIGRATION%20GUIDE.md
Next generation build tool?
The main popular build tools currently available are.
- webpack webpack is a static module bundler for modern JavaScript applications
- rollup Rollup is a module bundler for JavaScript
- Parcel Extreme zero-configuration web application packaging tool
- Snowpack The faster frontend build tool.
- vite The next generation frontend development and build tool
Javascript / typescript compilers.
- babel Babel is a JavaScript compiler
- tsc(typescript)
- esbuild Written in
Go
and mainly used for build acceleration - swc Super fast javascript / typescript compiler. written with
Rust
The core idea of Snowpack
and 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.
|
|
Key features/objectives.
- No bundles, true compile-on-demand, load-on-demand
- Extremely fast cold start
- Extremely fast hot updates
- Significantly improved development efficiency and experience
- More…
Main problems.
- 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
- More…