导航
导航
文章目录
  1. 准备工作
    1. node 版本
    2. 升级 webpack
    3. 检查依赖是否过期及升级相关包的版本
    4. 升级废弃的配置项
    5. 清理配置
  2. 踩坑记录点
    1. 1、webpack-dev-server配置属性变更
    2. 2、多入口开启 hot: true 热更新无效
    3. 3、JSON 模块需要使用具名导出
    4. 4、webpack-merge 变更
    5. 5、optimize-css-assets-webpack-plugin 变更(官方准备弃用了)
    6. 6、url-loader、file-loader、raw-loader(将来会被淘汰)
    7. 7、config.module.rules 里配置了 loaders
    8. 8、heap-eval-module-source-map 名称修改
    9. 9、copy-webpack-plugin 报错
    10. 10、去除 dll
    11. 11、cache 持久化缓存
    12. 12、Node Polyfill 脚本被移除
    13. 13、Module Federation
  3. 我的 webpack5 项目配置参考
  4. 总结
  5. 参考

webpack5升级之旅

前言:2020 年 10 月 10 日,webpack5 正式发布,并带来了诸多重大的变更,使前端的构建效率与质量大为提升。最近也是趁着空闲时间把项目里的 webapck4 进行了升级,接下来就介绍一下我的踩坑升级之旅吧。

准备工作

node 版本

Webpack 5 对 Node.js 的版本要求至少是 10.13.0 (LTS),如果还在使用旧版本的 Node.js,需要进行升级。

升级 webpack

1
yarn add webpack webpack-cli -D

检查依赖是否过期及升级相关包的版本

1
yarn outdated

将会列出package.json所有依赖的版本信息,包括当前安装版本,给予 semver 渴望的版本以及最新的版本。

接下来就说升级所有使用到的 plugin 和 loader 为最新的可用版本。

升级废弃的配置项

如有使用以下的配置项,请升级至最新的版本:

  • optimization.hashedModuleIds: trueoptimization.moduleIds: 'hashed'
  • optimization.namedChunks: trueoptimization.chunkIds: 'named'
  • optimization.namedModules: trueoptimization.moduleIds: 'named'
  • NamedModulesPluginoptimization.moduleIds: 'named'
  • NamedChunksPluginoptimization.chunkIds: 'named'
  • HashedModuleIdsPluginoptimization.moduleIds: 'hashed'
  • optimization.noEmitOnErrors: falseoptimization.emitOnErrors: true
  • optimization.occurrenceOrder: trueoptimization: { chunkIds: 'total-size', moduleIds: 'size' }
  • optimization.splitChunks.cacheGroups.vendorsoptimization.splitChunks.cacheGroups.defaultVendors
  • Compilation.entriesCompilation.entryDependencies
  • serveserve 已被移除,推荐使用 DevServer
  • Rule.query (从 v3 开始被移除) → Rule.options/UseEntry.options

清理配置

  • optimization.moduleIdsoptimization.chunkIds 从配置中移除,使用默认值会更合适,因为它们会在 production 模式 下支持长效缓存且可以在 development 模式` 下进行调试。
  • 将配置中使用的 [hash] 占位符改为 [contenthash]。效果一致,但事实证明会更为有效
  • 正则表达式参数的 IgnorePlugin,现已支持传入一个 options 对象:`new IgnorePlugin({ resourceRegExp: /regExp/ })

踩坑记录点

1、webpack-dev-server配置属性变更

  • contentBase -> static.directory
  • 移除 stats
  • 移除 disableHostCheck
  • openPage -> open
  • before -> onBeforeSetupMiddleware
  • after -> onAfterSetupMiddleware

以上列举了一些常用配置修改,具体 v3 升级到 v4 的迁移指南可以查看官方文档 https://github.com/webpack/webpack-dev-server/blob/master/migration-v4.md

2、多入口开启 hot: true 热更新无效

1
2
3
optimization: {
runtimeChunk: 'single'
},

具体可以查看webpack-dev-server/issues/2792

3、JSON 模块需要使用具名导出

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

4、webpack-merge 变更

1
2
3
4
5
// webpack 4.x
const merge = require('webpack-merge');

// webpack 5.x
const { merge } = require('webpack-merge');

5、optimize-css-assets-webpack-plugin 变更(官方准备弃用了)

使用官方推荐的新插件:css-minimizer-webpack-plugin

1
yarn add css-minimizer-webpack-plugin -D

6、url-loader、file-loader、raw-loader(将来会被淘汰)

官方推荐:资源模块

7、config.module.rules 里配置了 loaders

webpack5 不再支持 loaders 的属性,需要改成 use

1
2
3
4
{
test: /\.(sc|sa|c)ss$/,
use: ['style-loader', 'css-loader', 'postcss-loader', 'sass-loader'],
}

8、heap-eval-module-source-map 名称修改

需要改成 eval-cheap-module-source-map

9、copy-webpack-plugin 报错

ValidationError: Invalid options object. Copy Plugin has been initialized using an options object that does not match the API schema.

1
2
3
4
5
6
7
8
9
10
11
12
13
module.exports = {
plugins: [
// webpack 4.x
new CopyWebpackPlugin(['public'])

// webpack 5.x
new CopyWebpackPlugin({
patterns: [
{ from: 'public', to: 'public' }
]
})
]
}

10、去除 dll

在 webpack5 中已经不建议使用这种方式进行模块缓存,因为其已经内置了更好的 cache 方法

11、cache 持久化缓存

通过配置 cache 缓存生成的 webpack 模块和 chunk,来改善构建速度。

webpack5 默认将构建的缓存结果放在 node_modules/.cache 目录下,可以通过配置更改目录。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
module.exports = {
cache: {
// 将缓存类型设置为文件系统
type: 'filesystem',
buildDependencies: {
/* 将你的 config 添加为 buildDependency,以便在改变 config 时获得缓存无效 */
config: [__filename],
/* 如果有其他的东西被构建依赖,你可以在这里添加它们 */
/* 注意,webpack.config,加载器和所有从你的配置中引用的模块都会被自动添加 */
},
// 指定缓存的版本
version: '1.0',
},
};

Tips:

  • cache 的属性 type 会在开发模式下被默认设置成 memory,而且在生产模式中被禁用,所以如果想要在生产打包时使用缓存需要显式的设置。
  • 为了防止缓存过于固定,导致更改构建配置无感知,依然使用旧的缓存,默认情况下,每次修改构建配置文件都会导致重新开始缓存。当然也可以自己主动设置 version 来控制缓存的更新。

更多缓存配置可以参考官方文档 https://webpack.js.org/configuration/other-options/#cache

12、Node Polyfill 脚本被移除

webpack4 版本中附带了大多数 Node.js 核心模块的 polyfill,一旦前端使用了任何核心模块,这些模块就会自动应用,但是其实有些是不必要的。

webpack5 将不会自动为 Node.js 模块添加 polyfill,而是更专注的投入到前端模块的兼容中。因此需要开发者手动添加合适的 polyfill。

13、Module Federation

Module Federation 使得使 JavaScript 应用得以从另一个 JavaScript 应用中动态地加载代码 —— 同时共享依赖。相当于 webpack 提供了线上 runtime 的环境,多个应用利用 CDN 共享组件或应用,不需要本地安装 npm 包再构建了。

具体配置可以查看官方文档 https://webpack.js.org/concepts/module-federation/

我的 webpack5 项目配置参考

https://github.com/hzzlyxx/webpack5

总结

webpack5 正式发布已经有段时间了,总的来说:

  • 在加构建性能大幅度提升,依赖核心代码层面的持久缓存 cache,可大大加快二次构建速度
  • 在打包体积上能有效减少,依赖更优的 Tree Shaking
  • 默认支持浏览器长期缓存,降低配置门槛
  • 令人激动的新特性 Module Federation,蕴含极大的可能性

参考