本指南旨在帮助您在使用 webpack 时直接迁移到 webpack 5。如果您使用更高层的工具运行 webpack,请参阅该工具的迁移说明。
Webpack 5 至少需要 Node.js 10.13.0 (LTS),因此如果您还在运行旧版本,请确保升级您的 Node.js。
将 webpack 4 升级到可用的最新版本。
当使用 webpack >= 4 时,升级到最新的 webpack 4 版本不应需要额外的指导。
如果您使用的 webpack 版本低于 4,请参阅webpack 4 迁移指南。
将 webpack-cli 升级到可用的最新版本(如果使用)
将所有使用的插件和加载器升级到可用的最新版本
某些插件和加载器可能需要使用 Beta 版本才能与 webpack 5 兼容。请务必在升级时阅读每个插件/加载器的发布说明,因为最新版本可能只支持 webpack 5 并在 v4 中失败。在这种情况下,建议更新到支持 webpack 4 的最新版本。
为了协助从 webpack v4 升级到 v5,Codemod 提供了开源社区 codemod,可以帮助自动化大部分迁移过程。
请注意,这些不是官方的 webpack codemod,尽管它旨在简化迁移,但可能无法涵盖所有情况。您可能仍需要执行额外的手动步骤才能完全完成升级。
npx codemod@latest webpack/v5/migration-recipe
这将运行 Codemod 注册表中的以下 codemod
webpack/v5/set-target-to-false-and-update-pluginswebpack/v5/migrate-library-target-to-library-objectwebpack/v5/json-imports-to-default-imports这些 codemod 中的每一个都自动化了 webpack v5 迁移指南中列出的一个更改。有关可用 webpack v5 codemod 的完整列表,请参阅 Codemod 注册表。
由于 webpack、webpack-cli、插件和加载器版本的升级,可能会出现新的错误或警告。在构建过程中请注意弃用警告。
您可以这样调用 webpack 以获取弃用警告的堆栈跟踪,从而找出哪些插件和加载器是原因。
node --trace-deprecation node_modules/webpack/bin/webpack.js
由于 webpack 5 移除了所有弃用功能,因此请确保在构建过程中没有 webpack 弃用警告,以便继续。
mode将 mode 设置为 production 或 development,以确保设置了相应的默认值。
将以下选项更新到其新版本(如果使用)
optimization.hashedModuleIds: true → optimization.moduleIds: 'hashed'optimization.namedChunks: true → optimization.chunkIds: 'named'optimization.namedModules: true → optimization.moduleIds: 'named'NamedModulesPlugin → optimization.moduleIds: 'named'NamedChunksPlugin → optimization.chunkIds: 'named'HashedModuleIdsPlugin → optimization.moduleIds: 'hashed'optimization.noEmitOnErrors: false → optimization.emitOnErrors: trueoptimization.occurrenceOrder: true → optimization: { chunkIds: 'total-size', moduleIds: 'size' }optimization.splitChunks.cacheGroups.vendors → optimization.splitChunks.cacheGroups.defaultVendorsoptimization.splitChunks.cacheGroups.test(module, chunks) → optimization.splitChunks.cacheGroups.test(module, { chunkGraph, moduleGraph })Compilation.entries → Compilation.entryDependenciesserve → serve 已被移除,转而使用 DevServerRule.query (自 v3 起弃用) → Rule.options/UseEntry.optionsRule.loaders → Rule.use尝试在您的 webpack 4 配置中设置以下选项,并检查构建是否仍然正常工作。
module.exports = {
// ...
node: {
Buffer: false,
process: false,
},
};
在为 webpack 5 升级配置时,您必须再次移除这些选项。
现在让我们将 webpack 升级到版本 5
npm: npm install webpack@latest
Yarn: yarn add webpack@latest
如果您在“升级 webpack 4 及其插件/加载器”步骤中未能将某些插件/加载器升级到最新版本,请不要忘记现在升级它们。
考虑从您的 webpack 配置中移除 optimization.moduleIds 和 optimization.chunkIds。默认值可能更好,因为它们在 production mode 下支持长期缓存,在 development mode 下支持调试。
在 webpack 配置中使用 [hash] 占位符时,考虑将其更改为 [contenthash]。它们不一样,但后者被证明更有效。
如果您正在使用 Yarn 的 PnP 和 pnp-webpack-plugin,我们有个好消息:现在它默认受支持了。您必须将其从配置中移除。
如果您正在使用带有正则表达式作为参数的 IgnorePlugin,它现在接受一个 options 对象:new IgnorePlugin({ resourceRegExp: /regExp/ })。
如果您使用类似 node.fs: 'empty' 的配置,请将其替换为 resolve.fallback.fs: false。
如果您在 webpack Node.js API 中使用 watch: true,请将其移除。无需设置它,因为它由您调用的编译器方法指示,watch() 为 true,run() 为 false。
如果您为使用 raw-loader、url-loader 或 file-loader 加载资源定义了 rules,请改用 Asset Modules,因为它们将在不久的将来弃用。
如果您的 target 设置为一个函数,请将其更新为 false,并在 plugins 选项中应用该函数。请参阅以下示例
// for webpack 4
{
target: WebExtensionTarget(nodeConfig)
}
// for webpack 5
{
target: false,
plugins: [
WebExtensionTarget(nodeConfig)
]
}
注意:此更改的 Codemod
npx codemod webpack/v5/set-target-to-false-and-update-plugins(参见此处的注册表。)
如果您定义了 output.library 或 output.libraryTarget,请更改属性名称:(output.libraryTarget -> output.library.type,output.library -> output.library.name)。示例
// for webpack 4
{
output: {
library: 'MyLibrary',
libraryTarget: 'commonjs2'
}
}
// for webpack 5
{
output: {
library: {
name: 'MyLibrary',
type: 'commonjs2'
}
}
}
注意:此更改的 Codemod
npx codemod webpack/v5/migrate-library-target-to-library-object(参见此处的注册表。)
如果您通过导入使用 WebAssembly,则应遵循此两步过程
experiments.syncWebAssembly: true 来启用已弃用的规范,以获得与 webpack 4 中相同的行为。experiments 值更改为 experiments: { asyncWebAssembly: true },以使用最新的 WASM 集成规范。重新考虑 optimization.splitChunks
optimization.splitChunks: { chunks: 'all' }。name: false,并将 name: string | function 替换为 idHint: string | function。optimization.splitChunks.cacheGroups: { default: false, vendors: false } 可以关闭默认值。我们不建议这样做,但如果您确实想在 webpack 5 中获得相同的效果:optimization.splitChunks.cacheGroups: { default: false, defaultVendors: false }。考虑移除默认值
entry: './src/index.js':您可以省略它,这是默认值。output.path: path.resolve(__dirname, 'dist'):您可以省略它,这是默认值。output.filename: '[name].js':您可以省略它,这是默认值。如果您的项目启用了 browserslist,webpack 5 将重用您的 browserslist 配置来决定为运行时代码发出何种代码样式。
请务必
target 设置为 browserslist 或删除 target 让 webpack 自动为您设置 browserslist。IE 11 添加到您的 browserslist 配置中。如果没有 browserslist,webpack 的运行时代码使用 ES2015 语法(例如,箭头函数)来构建更小的包。因此,您需要设置 target: ['web', 'es5'] 以便为不支持 ES2015 语法的浏览器(如 IE11)使用 ES5 语法。
对于 Node.js,构建在 target 选项中包含受支持的 Node.js 版本,webpack 将自动找出支持的语法,例如 target: 'node8.6'。
/* webpackChunkName: '...' */请务必理解其意图
webpackChunkName,Webpack 5 也将在 development 模式下自动分配有用的文件名。新规范不支持此功能,您将收到警告。请勿使用
import { version } from './package.json';
console.log(version);
请改用
import pkg from './package.json';
console.log(pkg.version);
注意:此更改的 Codemod
npx codemod webpack/v5/json-imports-to-default-imports(参见此处的注册表。)
const compiler = webpack(...); 时,请务必在使用后关闭编译器:compiler.close(callback);。
webpack(..., callback) 形式。请务必仔细阅读构建错误/警告。如果没有相应的建议,请创建一个 issue,我们将尝试解决。
重复以下步骤,直到您解决了至少 3 级或 4 级问题
1 级:Schema 验证失败。
配置选项已更改。应该有一个带有 BREAKING CHANGE: 注释的验证错误,或者一个提示应该使用哪个选项的提示。
2 级:Webpack 退出并出现错误。
错误消息应该告诉您需要更改什么。
3 级:构建错误。
错误消息应该有 BREAKING CHANGE: 注释。
4 级:构建警告。
警告消息应该告诉您可以改进什么。
5 级:运行时错误。
这很棘手。您可能需要调试才能找到问题。这里很难给出一般性建议。但我们确实在下面列出了一些关于运行时错误的常见建议
process 未定义。
exports 或 imports package.json 字段根据环境使用不同的代码。
browser 字段来支持旧的打包工具。typeof process 检查包裹代码块。请注意,这会对 bundle 大小产生负面影响。process.env.VARIABLE 的环境变量吗?您需要使用 DefinePlugin 或 EnvironmentPlugin 在配置中定义这些变量。
VARIABLE 并确保同时检查 typeof VARIABLE !== 'undefined'。process.env 是 Node.js 特有的,应避免在前端代码中使用。auto 的 URL 的 404 错误output.publicPath: "auto" 实现的新默认自动 publicPath 做好准备output.publicPath: ""。plugins 部分中,并且该配置也设置为 production 模式,请从您的插件列表中移除该插件(即 new webpack.optimize.ModuleConcatenationPlugin())。在 webpack 5 中,该插件在生产模式下默认启用,它可能会被两次包含。6 级:弃用警告。
您可能会收到大量弃用警告。这本身并不是问题。插件需要时间来赶上核心变化。请将这些弃用报告给插件。这些弃用只是警告,构建仍会正常工作,只是有一些小缺点(例如性能较低)。
--no-deprecation 标志运行 node 来隐藏弃用警告,例如:node --no-deprecation node_modules/webpack/bin/webpack.js。这应该只是一个临时解决方案。7 级:性能问题。
通常,webpack 5 的性能应该会提升,但也有一些情况下性能会变差。
以下是一些可以改善情况的方法
--profile --progress 现在会显示一个简单的性能分析node --inspect-brk node_modules/webpack/bin/webpack.js + chrome://inspect / edge://inspect (参阅 profiler 标签页)。
--no-turbo-inlining 标志以获得更好的堆栈跟踪。module.unsafeCache: truedevtool 选项,了解不同选项的比较。请发推特告知您已成功迁移到 webpack 5。发推
创建一个问题,告诉我们您在迁移过程中遇到的问题。
请提交拉取请求,以帮助下一个使用本指南的人。
Webpack 内部的变化,例如:添加类型、代码重构和方法重命名,都列在这里供感兴趣的人参考。但它们不属于常见用例迁移的一部分。
Module.nameForCondition、Module.updateCacheModule 和 Module.chunkCondition 不再是可选的。Webpack 5 内置了 this.getOptions 方法,可在 loader 上下文中使用。对于之前使用 schema-utils 的 getOptions 方法的 loader 来说,这是一个破坏性更改。
this.getOptions 在 webpack 5 中可用?{arg:true} → ?{"arg":true}。在相应 Loader 的文档中,使用 JSON5 应该被视为已弃用,并记录为支持 JSON。loader-utils 在解析查询字符串时有特定的行为(true、false 和 null 将不会被解析为 string,而是作为原始值)。对于新的内置 this.getOptions 方法来说,情况不再如此,它使用原生的 querystring 解析(随 Node.js 提供)。在通过 this.getOptions 方法获取选项后,仍然可以在 Loader 的代码中为这些情况添加自定义行为。this.getOptions 方法是可选的,但我们强烈建议为您的 Loader 选项添加 schema 验证。schema 中的 title 字段可用于自定义验证错误消息,例如 "title": "My Loader ooooptions" 将导致错误显示为: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.