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.
webpack 5 requires at least Node.js 10.13.0 (LTS).
Using newer Node.js version can improve build performance.
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
, andfile-loader
should be replaced using the new built-in Asset Modules feature.
ExtendedAPIPlugin is removed and the logic is merged into
APIPlugin
.
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.
If you are using HtmlWebpackPlugin skip this step.
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.
mode
Set mode to either production
or development
to make sure that corresponding defaults are set.
Update the following options to their new version (if used):
optimization.hashedModuleIds: true
↦ optimization.moduleIds: 'deterministic'
optimization.namedChunks: true
↦ optimization.chunkIds: 'named'
optimization.namedModules: true
↦ optimization.moduleIds: 'named'
NamedModulesPlugin
↦ optimization.moduleIds: 'named'
NamedChunksPlugin
↦ optimization.chunkIds: 'named'
HashedModuleIdsPlugin
↦ optimization.moduleIds: 'deterministic'
optimization.noEmitOnErrors: false
↦ optimization.emitOnErrors: true
optimization.occurrenceOrder: true
↦ optimization: { chunkIds: 'total-size', moduleIds: 'size' }
optimization.splitChunks.cacheGroups.vendors
↦ optimization.splitChunks.cacheGroups.defaultVendors
Compilation.entries
↦ Compilation.entryDependencies
serve
↦ serve
is removed in favor of DevServer
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.
npm: npm install webpack@latest --dev
Yarn: yarn add webpack@latest -D
Consider removing optimization.moduleIds
and optimization.chunkIds
from your webpack configuration. The defaults could be better, because they support long term caching in production mode
and debugging in development
mode.
When using [hash]
placeholder in webpack configuration, consider changing it to [contenthash]
. It is not the same, but proven to be more effective.
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 node.something: 'empty'
replace it with resolve.fallback.something: false
.
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:
experiments.syncWebAssembly: true
, to get the same behavior as in webpack 4.experiments
value to experiments: { asyncWebAssembly: true }
to use the up-to-date spec for WASM integration.Reconsider optimization.splitChunks
:
optimization.splitChunks: { chunks: 'all' }
.name: false
and replace name: string | function
with idHint: string | function
.optimization.splitChunks: { default: false, vendors: false }
. We don't recommend doing this, but if you really want to get the same effect in webpack 5: optimization.splitChunks: { default: false, defaultVendors: false }
.Consider removing defaults:
entry: './src/index.js'
: you can omit it, that's the default.output.path: path.resolve(__dirname, 'dist')
: you can omit it, that's the default.output.filename: '[name].js'
: you can omit it, that's the default.Need to support an older browser?
target: ["web", "es5"]
to change it to ES5.target
option and webpack will automatically figure out which syntax is supported, e.g. target: 'node8.6'
.Using /* webpackChunkName: '...' */
: Make sure to understand the intention:
development
mode even when not using webpackChunkName
.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);
const compiler = webpack(...);
, make sure to close the compiler after using it: compiler.close(callback);
. webpack(..., callback)
form which automatically closes.Please make sure to read errors/warnings carefully.
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 difficult 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.
Regarding Runtime Errors:
process
is not defined. exports
or imports
package.json field to use different code depending on the environment. browser
field to support older bundlers,.typeof process
checks. Note that this will have a negative impact on the bundle size.process.env.VARIABLE
? You need to use the DefinePlugin
or EnvironmentPlugin
to define these variables in the configuration. VARIABLE
instead and make sure to check typeof VARIABLE !== 'undefined'
too. process.env
is Node.js specific and should be avoided in frontend code.auto
publicPath
via output.publicPath: "auto"
output.publicPath: ""
instead.Regarding Deprecation Warnings:
--no-deprecation
flag, e.g.: node --no-deprecation node_modules/webpack/bin/webpack.js
. This should only be a temporary workaround.Regarding Performance issues:
--profile --progress
displays a simple performance profile nownode --inspect-brk node_modules/webpack/bin/webpack.js
+ chrome://inspect
/ edge://inspect
(see profiler tab). --no-turbo-inlining
flag for better stack traces in some casesmodule.unsafeCache: true
devtool
option in the documentation to see a comparison of the different options.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).
Please tweet that you have successfully migrated to webpack 5. Tweet it
Create an issue and tell us about the issues you have encountered during the migration.
Please open a Pull Request to help the next person using this guide.
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.
Module.nameForCondition
, Module.updateCacheModule
and Module.chunkCondition
are no longer optional.webpack 5 ships with built-in this.getOptions
method available in loader context. This is a breaking change for loaders that had been using getOptions
method from previously preferred schema-utils:
this.getOptions
is available since webpack 5?{arg:true}
↦ ?{"arg":true}
. Using JSON5 should be considered and documented as deprecated in favor of JSON in respective Loader's documentation.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 after getting the options by using this.getOptions
method.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.