To v5 From v4 - Webpack
To v5 From v4 - Webpack
This guide aims to help you migrating to webpack 5 when using webpack directly. If you are using a higher
level tool to run webpack, please refer to the tool for migration instructions.
Preparations
webpack 5 requires at least Node.js 10.13.0 (LTS).
When using webpack >= 4, upgrading to the latest webpack 4 version should not require additional
guidance. If you are using webpack version less than 4 please see the webpack 4 migration guide.
Some Plugins and Loaders might have a beta version that has to be used in order to be compatible with
webpack 5.
Check related Plugins and Loaders migration guide when upgrading across major versions. Several
commonly-used loaders like raw-loader , url-loader , and file-loader should be replaced
using the new built-in Asset Modules feature.
There might be new errors or warnings because of the upgraded versions of webpack, webpack-cli, Plugins
and Loaders. Keep an eye for deprecation warnings during the build.
You can invoke webpack this way to get stack traces for deprecation warnings to figure out which Plugins
and Loaders are responsible.
node --trace-deprecation node_modules/webpack/bin/webpack.js
webpack 5 removes all deprecated features. In order to proceed, there should be no webpack
deprecation warnings during the build.
Make sure you are using entry point information from stats
When using static HTML or creating HTML in other way, make sure to use entry points from stats JSON to
generate <script> , <style> and <link> tags.
If this is not possible, avoid setting splitChunks.chunks: 'all' and splitChunks.maxSize later
in this guide. Note that this is sub-optimal and a workaround.
Set mode to either production or development to make sure that corresponding defaults are set.
optimization.splitChunks.cacheGroups.vendors ↦
optimization.splitChunks.cacheGroups.defaultVendors
Compilation.entries ↦ Compilation.entryDependencies
Try to set the following options in your webpack 4 configuration and check if build still works correctly.
module.exports = {
// ...
node: {
Buffer: false,
process: false
}
};
webpack 5 removes these options from the configuration schema and will always use false .
You have to remove these options again when upgrading your configuration for webpack 5.
Clean up configuration
If you are using Yarn's PnP and the pnp-webpack-plugin , we have good news: it is supported by
default now. You have to remove it from the configuration.
If you are using IgnorePlugin with a regular expression as argument, it takes an options object
now: new IgnorePlugin({ resourceRegExp: /regExp/ }) .
If you are using watch: true in webpack Node.js API, remove it. There's no need to set it as it's
indicated by the compiler method you call, either true for watch() or false for run() .
If you have rules defined for loading assets using raw-loader , url-loader , or file-
loader , these should be configured as Asset Modules instead.
If you have target set to a function, update it to false and apply that function within plugins
option. See example below:
// for webpack 4
{
target: WebExtensionTarget(nodeConfig)
}
// for webpack 5
{
target: false,
plugins: [
WebExtensionTarget(nodeConfig)
]
}
If you were using WebAssembly via import, you should follow this two step process:
Enable the deprecated spec by setting experiments.syncWebAssembly: true , to get the same
behavior as in webpack 4.
Reconsider optimization.splitChunks :
When using a custom configuration, drop name: false and replace name: string |
function with idHint: string | function .
Using entry: './src/index.js' : you can omit it, that's the default.
Using output.path: path.resolve(__dirname, 'dist') : you can omit it, that's the default.
Using output.filename: '[name].js' : you can omit it, that's the default.
By default, webpack will use your browserslist config to decide which code style to emit.
Without a browserslist it would emit ES6 style. You can use target: ["web", "es5"] to change
it to ES5.
For Node.js, builds include the supported Node.js version in the target option and webpack will
automatically figure out which syntax is supported, e.g. target: 'node8.6' .
Using named exports from JSON modules: this is not supported by the new specification and you will get a
warning. Instead of import { version } from './package.json'; console.log(version);
use import package from './package.json'; console.log(package.version);
This doesn't apply to the webpack(..., callback) form which automatically closes.
This is optional if you use webpack in watching mode until the user ends the process. The idle
phases in watch mode will be used for this kind of work.
If there is no corresponding advise? Please create an issue and we will try to resolve it. Repeat this step
until you solved at least level 3 or 4:
Level 1: Schema validation fails. Configuration options have changed. There should be a validation
error with a BREAKING CHANGE: note, or a hint which option should be used instead.
Level 2: webpack exits with an error. The error message should tell you what needs to be changed.
Level 3: Build Errors. The error message should have a BREAKING CHANGE: note.
Level 4: Build Warnings. The warning message should tell you what can be improved.
Level 5: Runtime Errors. This is tricky. You probably have to debug to find the problem. A general
advise is di icult here.
Level 6: Deprecation Warnings. You probably get a lot of deprecation warnings. This is not directly a
problem. Plugins need time to catch up with core changes. Please report these deprecations to the
plugins. These deprecations are only warnings and the build will still work with only minor drawbacks
(like less performance).
Level 7: Performance issues. Usually performance should improve with webpack 5, but there are also
a few cases where performance get worse.
webpack 5 does no longer include a polyfill for this Node.js variable. Avoid using it in the
frontend code.
Want to support frontend and browser usage? Use the exports or imports
package.json field to use di erent code depending on the environment.
Alternative: Wrap code blocks with the typeof process checks. Note that this will
have a negative impact on the bundle size.
Want to use environment variables with process.env.VARIABLE ? You need to use the
DefinePlugin or EnvironmentPlugin to define these variables in the configuration.
Consider using VARIABLE instead and make sure to check typeof VARIABLE !==
'undefined' too. process.env is Node.js specific and should be avoided in
frontend code.
Not all ecosystem tooling is ready for the new default automatic publicPath via
output.publicPath: "auto"
You can hide deprecation warnings by running node with --no-deprecation flag, e.g.: node
--no-deprecation node_modules/webpack/bin/webpack.js . This should only be a
temporary workaround.
Plugins and Loaders contributors can follow the advises in the deprecation messages to improve
the code.
Regarding Performance issues:
You can save these profiles to files and provide them in issues.
Try using --no-turbo-inlining flag for better stack traces in some cases
Time for building modules in incremental builds can be improved by reverting to unsafe caching
like in webpack 4:
module.unsafeCache: true
But this might a ect the ability to handle some of the changes to the code base
Full build
Backward-compatibility layer for the deprecated features will usually have worse
performance compared to the new features.
Creating many warnings can a ect build performance, even if they are ignored.
Source Maps are expensive. Check devtool option in the documentation to see a
comparison of the di erent options.
Anti-Virus protection might a ect performance of the file system access.
Persistent Caching can help to improve the repetitive full builds.
Module Federation allows to split the application into multiple smaller builds.
By default, webpack's runtime code uses ES2015 syntax to build smaller bundles. If your build targets
environments that don't support this syntax (like IE11), you'll need to set target: ['web', 'es5'] to
revert to ES5 syntax ( 'web' if target environment is browser).
Everything works?
It is not working?
Create an issue and tell us about the issues you have encountered during the migration.
Changes to internals
The changes to webpack internals such as: adding types, refactoring code and methods renaming are
listed here for anyone interested. But they are not intended as a part of common use-case migration.
loader-utils has specific behavior for parsing query strings ( true , false and null won't
be parsed as string but as a primitive value). This is no longer the case for the new built-in
this.getOptions method, which uses native querystring parsing (ships with Node.js). It is
still possible to add custom behavior for these cases in the Loader's code a er getting the options by
using this.getOptions method.
Schema argument is optional for the new this.getOptions method, but we strongly advise to
add schema validation for your Loader's options. The title field in the schema, can be used to
customize the validation error message e.g. "title": "My Loader ooooptions" will result in
displaying errors this way: Invalid ooooptions object. My Loader has been initialised
using an ooooptions object that does not match the API schema. -
ooooptions.foo.bar.baz should be a string.
« Previous Next »
Migrate To v4 from v3