准备工作

2023-05-31 11:58 更新

Webpack 5 对 Node.js 的版本要求最低是 10.13.0 (LTS),因此,如果你还在使用旧版本的 Node.js,请升级它们。

升级 webpack 4 及其相关的插件/加载器

  1. 升级 webpack 4 至最新的可用版本。
  • 当使用webpack >= 4时,升级到最新的webpack 5版本无需额外的操作。
  • 如果您使用的 webpack 版本小于 4,请查看 webpack 4 迁移指南

2. 升级 webpack-cli 到最新的可用版本(如已使用的情况下)

3. 升级所有使用到的插件和加载器为最新的可用版本。

部分插件和加载器可能会有一个 beta 版本,必须使用它们才能与 webpack 5 兼容。 请确保在升级时阅读每个插件/加载器的发布说明,因为最新版本可能只支持webpack 5,而在v4中会运行失败。在这种情况下,建议升级到支持 webpack 4 的最新版本。

确保你的结构没有错误或警告

由于升级了webpack,webpack-cli,plugin以及loader的版本,因此,可能会出现新的错误或警告。在编译过程中请注意是否有废弃警告。

你可以通过如下方式调整 webpack 来获取堆栈信息中的废弃警告,从中找到是哪个插件或者 loader 构建的。

node --trace-deprecation node_modules/webpack/bin/webpack.js

由于webpack 5移除了所有被废弃的特性,因此,需要确保在构建过程中没有webpack的废弃警告才能继续。

请确保设置了模型

将模型设置为 ​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: true
  • optimization.occurrenceOrder: true​ → ​optimization: { chunkIds: 'total-size', moduleIds: 'size' }
  • optimization.splitChunks.cacheGroups.vendors​ → ​optimization.splitChunks.cacheGroups.defaultVendors
  • optimization.splitChunks.cacheGroups.test(module, chunks) ​→ ​optimization.splitChunks.cacheGroups.test(module, { chunkGraph, moduleGraph })
  • Compilation.entries​ → ​Compilation.entryDependencies
  • serve​ → ​serve​ 已被移除,推荐使用 ​DevServer
  • Rule.query​(从 v3 开始被移除)→ ​Rule.options​/​UseEntry.options
  • Rule.loaders​ → ​Rule.use

测试 webpack 5 兼具性

尝试在 webpack 4 的配置中添加如下选项,检查一下构建是否仍然正确的运行。

module.exports = {
  // ...
  node: {
    Buffer: false,
    process: false,
  },
};

你必须在升级 webpack 5 的配置时,必须删除这些选项。

清理配置

2023-05-31 13:55 更新

现在,让我们升级到 webpack 5:

  • npm: npm 安装 webpack@latest
  • 纱线:纱线添加webpack@latest

如果你之前在升级 webpack 4 时不能将任何插件或加载器升级到最新版本,现在不要忘了升级。

清理配置

  • 请考虑 ​optimization.moduleIds​ 和 ​optimization.chunkIds​ 从你的webpack配置中移除。使用默认值会更合适,因为它们会在 production 模式 下支持长效缓存且可以在 development 模式下进行调试。
  • 当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​ 。
  • 如果您确定了 ​rules​ ,则使用 ​raw-loader​ ,​ url-loader​ 或 ​file-loader​ 来加载资源,请使用 资源模板 替代,因为它们可能会在不久的将来被淘洗。
  • 如果你将 ​target​ 标记设置为函数,则应将其更新为 ​false​ ,然后在插件中选择使用该函数。具体示例如下:
// for webpack 4
{
    target: WebExtensionTarget(nodeConfig)
}

// for webpack 5
{
    target: false,
    plugins: [
        WebExtensionTarget(nodeConfig)
    ]
}

如果通过 import 使用了 WebAssembly,应遵循以下两点:

  • 在配置增加 ​experiments.syncWebAssembly: true​ 配置,以启动废弃提示,获得在webpack 4中的一致为。
  • 在成功升级至 webpack 5 以后,应将 ​experiments​ 的值改为 ​experiments:{ asyncWebAssembly: true }​ 以使用最新规范的 WASM。

重新考虑 ​optimization.splitChunks​ 的配置:

  • 推荐使用默认配置或使用优化。​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'​ 时:你可以省略它,此为默认值。

需要旧版浏览器的支持?比如IE 11?

  • 如果你在项目中启用了 browserslist ,webpack 5 将会重新使用你的 ​browserslist​ 配置来决定运行时的代码风格。

只需要确保:

1. 将目标设置为browserslist,或者转移者移除target配置,webpack会自动将其置为 browserslist

2. 在你的 ​browserslist​ 配置中添加​ IE 11​ 。

  • 如果未使用 ​browserslist​ ,webpack 的运行时代码将默认使用 ES2015 语言法(例如,箭头数)来构建一个简洁的 bundle。如果你构建构建的目标环境并不支持 ES2015 的语言(如 IE 11),你需要设置 ​target:['web', 'es5']​ 以使用 ES5 的语言。
  • 对于Node.js环境来说,构建中引入了对Node.js版本的支持,webpack会自动找到对应用版本支持的语言,例如,​target: 'node8.6'​ 。
  • 清理代码

    2023-05-31 14:27 更新

    使用 ​/* webpackChunkName: '...' */​ 时

    请确保你了解了其含义图:

    • 此处 chunk 的名称本意是 public 的。
    • 它不仅是用于开发模式的名称。
    • webpack 会在 production 以及 development 的模式中使用它对文件进行命名。
    • 即使用不使用 ​webpackChunkName​,webpack 5也会自动在 ​development​ 模式下分配有意义的文件名。

    为 JSON 模块使用工具名称导出

    新规中将不再支持下面这种方式,如此做会发出警告:

    import { version } from './package.json';
    console.log(version);

    请使用如下方式替代:

    import pkg from './package.json';
    console.log(pkg.version);

    清理构造代码

    • 当使用 ​const compiler = webpack(...);​ ,确保在使用完成后,使用​compiler.close(callback);​ 关闭编译器。
    • 这不适合用于自动关闭的 ​webpack(..., callback)​ 。
    • 如果你在监听模式下使用webpack,直接连接到用户绑定进程,此可选。在监听模式下面的空闲阶段将被用于执行此操作。

    运行单个结构并遵循以下建议

    请事务必须仔细阅读构建时的错误/警告。如未发现相关建议,请创建一个issue,我们将尽全力解决。

    重新按照下面步骤,直到你至少解决到 Level 3 或 Level 4:

    • Level 1: 模型(Schema)校试失败

    配置选项已更改。应该要有校试失败的信息并附上 ​BREAKING CHANGE:​ 提示,或提示应用哪一个选项。


    • Level 2: webpack 异常退出并出现错误

    错误信息告诉你哪里需要进行修改。


    • 等级3:构建错误

    错误信息应该要有 BREAKING CHANGE: 提示。


    • Level 4: 构建警告

    警告信息应该告诉你哪里需要进行修改。


    • Level 5: 运行时错误

    这很棘手,你可能需要调试才能找到问题所在。在这里很难给出一个通用的建议。但是我们在下面列出了一些关于运行时错误的常见建议:

    1. ​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 特有,应避免在前端中使用。

    2. 404错误将指向包含 auto 的 URL

    • 并非所有生态系统工具都已设置好的新 ​publicPath​ 的默认值 ​output.publicPath: "auto"
    • 使用静态的 ​output.publicPath: ""​ 代替。

    • Level 6: 弃用警告

    你可能会收到很多弃用警告,插件需要时间来赶上内部的变化。请将这些弃用上报给插件。这些弃用只是警告,构建仍然可以正常工作,只是会有小瑕疵(比如性能降低)。

    1. 你使用带有 ​--no-deprecation​ 选项的 node 运行 webpack ,可以可以隐藏废弃告警,例如:  ​node --no-deprecation node_modules/webpack/bin/webpack.js​ 。但这只能作为临时的解决方案。
    2. plugin 和 loader 的开发者,应遵循弃用信息中的建议以改进代码。

    • Level 7: 性能问题

    一般来说,webpack 5 的性能应该会有所提高,但也存在少数情况性能会变差。

    而在这里,你可以做一些事情来改善这种情况:

    1. 通过 Profile 检查时间花费在哪里。

    • --profile --progress​ 可以显示一个简单的性能目标。
    • node --inspect-brk node_modules/webpack/bin/webpack.js + chrome://inspect ​/  ​edge://inspect​  。
    • 你可以将这些性能文件保存到文件中,并在 issues 中提供它们。
    • 尝试使用 ​--no-turbo-inlining​ 选项,在某些情况下可以获得更好的堆栈信息。

    2. 在增量构建时,构建模块的世界可以通过使用像 webpack 4 中的不安全缓存来改善:

    • module.unsafeCache: true
    • 但是这可能会影响处理代码库的一些变化能力。

    3. 全量构建

    • 与新功能相比,弃用特性的向后兼容层通常性能很差。
    • 创建许多警告会影响构建性能,即使它们被忽略。
    • Source Maps 的代价很昂贵。请在文档中查看 ​devtool​ 选项以比较使用不同选项的代价。
    • Anti-Virus(反病毒)保护可能会影响文件系统的访问性能。
    • 持久缓存可以帮助改善重复性的完整构建。
    • Module Federation 允许将应用程序分割成多个较小的构建。
    • 后续工作

      2023-05-31 14:33 更新

      所有的情况都运行得如常吗?

      如果你成功地迁移到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}​。在相关的加载器文档中,应用推荐使用 JSON 而不是推荐使用JSON5。
      • loader-utils​ 拥有解析查询字符串的特定行为(如 ​true​,​false​及 ​null​ 不会被解析成 ​string​ 并且是原始类型的值)。这对新的内部设置 ​this.getOptions​ 方法来说,不再适用,它使用Node原生的 ​querystring​ 方法进入解析。此时,需要在loader中使用 ​this.getOptions​ 获取配置选项之后,根据情况添加自主权为行。
      • 模式(Schema) 参看新的 ​this.getOptions​ 方法而言是可以选择的,但是我们强烈建议给你的加载器选择项添加模式校试。模式中的 ​title​ 字段,可用于自定校园实验的错误信息,比如 ​"title": "My Loader oooptions"​ 会在这种方式显示错误信息: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.

By alex

4 thoughts on “webpack v4迁移到v5”
  1. Hi there,

    My name is Mike from Monkey Digital,

    Allow me to present to you a lifetime revenue opportunity of 35%
    That's right, you can earn 35% of every order made by your affiliate for life.

    Simply register with us, generate your affiliate links, and incorporate them on your website, and you are done. It takes only 5 minutes to set up everything, and the payouts are sent each month.

    Click here to enroll with us today:
    https://www.monkeydigital.org/affiliate-dashboard/

    Think about it,
    Every website owner requires the use of search engine optimization (SEO) for their website. This endeavor holds significant potential for both parties involved.

    Thanks and regards
    Mike Hoggarth

    Monkey Digital

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注