迁移
1、webpack 5 要求至少 Node.js 10.13.0 (LTS)。
2、将 webpack 4 升级到最新的可用版本
3、将 webpack-cli 升级到最新的可用版本 (当有使用的时候)
4、将所有使用的 plugin 和 loader 升级到最新的可用版本
必须使用已适配 webpack 5 的 plugin 和 loader,它们可能存在 beta 版本。
当你升级到重大版本的时候,请参考相关 plugin 和 loader 的迁移指南。
ExtendedAPIPlugin 已被移除,它的逻辑已经被整合到APIPlugin
当中。
5、确保你的构建没有错误与警告
你可以使用如下方式调用 webpack,以追踪废弃告警的栈堆信息,并推断出是由哪个 plugin 或 loader 引起的。
node --trace-deprecation node_modules/webpack/bin/webpack.js
webpack 5 会移除所有废弃的特性。为了无障碍的推进,应保证在构建时再无任何的废弃警告。
6、确保你使用的是 stats 中的入口信息
如果你正使用 HtmlWebpackPlugin,可跳过该步骤。
... 不说了
7、请确保设置了 mode
(production or development)
8、升级废弃的配置项
如有使用以下的配置项,请升级至最新的版本:
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'
HashedModulesPlugin
↦optimization.moduleIds: 'hashed'
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
已被移除,推荐使用DevServer
9、测试 webpack 5 兼容性
尝试在 webpack 4 的配置中添加如下选项,检查一下构建是否仍然正确的运行。
module.exports = {
// ...
node: {
Buffer: false,
process: false
}
};
webpack 5 移除的配置会永远设置成false
。
在升级至 webpack 5 时,必须删除这些配置。
10、升级 webpack 版本
yarn add webpack@next -D
11、清理配置
- 请考虑将
optimization.moduleIds
和optimization.chunkIds
移除。
使用默认值会更合适,因为它们会在production 模式
下支持长效缓存,并且可以在development
模式下进行调试。
- 当 webpack 配置中使用了
[hash]
占位符时,请考虑将它改为[contenthash]
。效果一致,但事实证明会更为有效。 - 如果你使用了 Yarn 的 PnP 以及
pnp-webpack-plugin
插件,你可以将其从配置中移除,因为它已被默认支持。 - 如果你使用了带有正则表达式参数的
IgnorePlugin
,现已支持传入一个options
对象:new IgnorePlugin({ resourceRegExp: /regExp/ })
。 - 如果你使用了
node.something: 'empty'
,请使用resolve.fallback.something: false
代替。
如果通过 import 使用了 WebAssembly,应遵循以下两点:
- 在配置增加
experiments.syncWebAssembly: true
配置,以启用废弃提醒,获得在 webpack 4 中的相同行为。 - 在成功升级至 webpack 5 以后,应将
experiments
的值改为experiments: { asyncWebAssembly: true }
以使用最新规范的 WASM。
重新考虑 optimization.splitChunks
的配置:
- 推荐使用默认配置或使用
optimization.splitChunks: { chunks: 'all' }
配置。 - 当使用自定义配置时,请删除
name: false
,并将name: string | function
替换为idHint: string | function
。 - 使用
optimization.splitChunks: { default: false, vendors: false }
配置可以关闭默认值。但我们不推荐这么做,如果你需要在 webpack 5 中获得与之相同的效果:请将配置改为optimization.splitChunks: { default: false, defaultVendors: false }
。
考虑移除的默认值:
- 当设置
entry: './src/index.js'
时,你可以省略它,此为默认值。 - 当设置
output.path: path.resolve(__dirname, 'dist')
时:你可以省略它,此为默认值。 - 当设置
output.filename: '[name].js'
时:你可以省略它,此为默认值。
需要旧版浏览器的支持?
- 默认情况下,webpack 会使用你的 browserslist 配置来决定 emit 哪种代码样式。
- 如果未使用 browserslist,则默认为 ES6 风格。你可以使用
target: ["web", "es5"]
将其改为 ES5。 - 对于 Node.js 来说,在构建时支持在
target
中配置版本,webpack 会自动找出支持的语法,例如,target: 'node8.6'
。
12、清理代码
使用 /* webpackChunkName: '...' */
时:请确保你了解其意图:
- 此处 chunk 的名称本意是 public 的。
- 它不只是用于开发模式的名称。
- webpack 会在 production 以及 development 的模式中使用它对文件进行命名。
- 即使不使用
webpackChunkName
,webpack 5 也会自动在development
模式下分配有意义的文件名。
对 JSON 模块使用命名导出:新规范中已不再支持此功能,因此会收到警告。请使用 import package from './package.json'; console.log(package.version);
替换 import { version } from './package.json'; console.log(version);
。
清理构建代码
- 当使用
const compiler = webpack(...);
,确保在使用完毕后,使用compiler.close(callback);
关闭编译器。 - 这不适用于自动关闭的
webpack(..., callback)
。 - 如果你在监听模式下使用 webpack,直到用户结束进程,此为可选。在监听模式下的空闲阶段将被用于执行此工作。
运行单个构建并遵循以下建议
请务必仔细阅读错误/警告。
如果报错没有相关的建议?请创建一个 issue,我们会尝试解决它。
其它情况重复以下的步骤,直到你至少解决到 Level 3 或 Level 4:
- Level 1: 模式(Schema)校验失败。配置选项已更改。应该要有校验失败的信息且附上
BREAKING CHANGE:
提示,或提示应该使用哪个选项。 - Level 2: webpack 异常退出并出现错误。错误信息应告诉你哪里需要进行修改。
- Level 3: 构建错误。错误信息应该要有
BREAKING CHANGE:
提示。 - Level 4: 构建警告。警告信息应该告诉你哪里需要进行修改。
- Level 5: 运行时错误。这很棘手,你可以要调试才能找到问题所在。一般的建议在这很难有用。
- Level 6: 弃用警告。你可能会收到很多弃用警告,插件需要时间来赶上内核的变化。请将这些弃用上报给插件。这些弃用只是警告,构建仍然可以正常工作,只是会有小瑕疵(比如性能降低)。
- Level 7: 性能问题,一般来说,webpack 5 的性能应该会有所提高,但也存在少数情况性能会变差。
关于运行时错误:
process
未定义。- webpack 5 不再引入 Node.js 变量的 polyfill,在前端代码中应避免使用。
想支持前端和浏览器的用法?使用
exports
或imports
中的 package.json 字段,会根据环境不同使用不同的代码。- 也可以使用
browser
字段来支持旧的 bundlers。 - 替代方案。用
typeof process
检查包裹的代码块。请注意,这将对 bundle 大小产生负面影响。
- 也可以使用
想要使用环境变量,如
process.env.VARIABLE
?你需要使用DefinePlugin
或EnvironmentPlugin
在配置中定义这些变量。- 考虑使用
VARIABLE
代替,但需要检查typeof VARIABLE !== 'undefined'
。process.env
是 Node.js 特有,应避免在前端中使用。
- 考虑使用
404 的 error 将指向含有
auto
的 URL并非所有生态系统工具都已设置好新的
publicPath
的默认值output.publicPath: "auto"
- 使用静态的
output.publicPath: ""
代替。
- 使用静态的
关于弃用警告:
- 你使用带有
--no-deprecation
选项的 node 运行 webpack,可以隐藏废弃告警,例如:node --no-deprecation node_modules/webpack/bin/webpack.js
。但这只能作为临时的解决方案。 - plugin 和 loader 的开发者,应遵循弃用信息中的建议以改进代码。
- 你使用带有
关于性能问题:
通过 Profile 检查时间耗费在哪里。
--profile --progress
可以展示一个非常简单的性能曲线。node --inspect-brk node_modules/webpack/bin/webpack.js
+chrome://inspect
/edge://inspect
(查看 profiler 选项)。- 你可以将这些性能文件保存到文件中,并在 issues 中提供它们。
- 尝试使用
--no-turbo-inlining
选项,在某些情况下可以获得更好的堆栈信息。
在增量构建时,构建模块的世界可以通过使用像 webpack 4 中的不安全缓存来改善:
module.unsafeCache: true
- 但这可能会影响处理代码库的一些变化能力。
全量构建
- 与新功能相比,弃用特性的向后兼容层通常性能很差。
- 创建许多警告会影响构建性能,即使它们被忽略。
- Source Maps 的代价很昂贵。请在文档中查看
devtool
选项以比较使用不同选项的代价。 - Anti-Virus(反病毒)保护可能会影响文件系统的访问性能。
- 持久缓存可以帮助改善重复性的完整构建。
- Module Federation 允许将应用程序分割成多个较小的构建。
如有需要,在 runtime 代码中禁用 ES2015 语法
默认地,webpack 的 runtime 代码会使用 ES2015 语法以使得构建出来的包体积更小。如果你构建的目标环境中不支持这种语法(比如 IE11),你需要设置 target: ['web', 'es5']
将代码转换为 ES5 语法(如果 target 环境是浏览器,设置为 'web'
)。
所有情况都运行如常?
如果你成功地迁移至 webpack 5。请[发推 @ 我们]
运行异常?
创建一个 issue 并告诉我们在迁移过程中你遇到的问题。
发现本指南中缺失的东西?
请提交 Pull Request 以帮助其他开发者更好地使用该指南。
内核的改变
如果你对内核感兴趣,此处会列出 webpack 内核相关的变更,如:添加类型,代码重构和方法重命名等。但这些变化并不会作为迁移通用案例的一部份。
Module.nameForCondition
,Module.updateCacheModule
以及Module.chunkCondition
不再可选。
loader 的 getOptions 方法
webpack 5 发布后,在 loader 的上下文中,会带有内置的 this.getOptions
方法。这对于那些使用之前推荐 schema-utils 中的 getOptions
方法的 loader 而言,这是一个重大更新:
this.getOptions
自 webpack 5 起支持使用- 它支持将 JSON 作为查询字符串,而不仅仅是 JSON5:如
?{arg:true}
↦?{"arg":true}
。在相应的 loader 文档中,应推荐使用 JSON 并不推荐使用 JSON5。 loader-utils
拥有解析查询字符串的特定行为(如true
,false
以及null
不会被解析成string
而是原始类型的值)。这对于新的内置this.getOptions
方法来说,不再适用,它使用 Node 原生的querystring
方法进行解析。此时,需在 loader 中使用this.getOptions
获取配置选项之后,根据情况添加自定义行为。- 模式(Schema) 参数对新的
this.getOptions
方法而言是可选的,但我们强烈建议给你的 loader 选项添加模式校验。模式中的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.
。
一、改进
- 持久化缓存
- 更好的算法和默认值改进长期缓存
- 更好的tree shaking
特点
- webpack 5 会移除所有废弃的特性。为了无障碍的推进,应保证在构建时再无任何的废弃警告。
- mode 必须
升级记录
Error: Conflict: Multiple chunks emit assets to the same filename webpack-numbers.js
输出文件名冲突 ,用[name].js
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。