webpack升级
一、调研
对比维度 | Webpack 4 状态 | Webpack 5 改进与优势 |
构建速度 | 较慢,增量构建效率低 | ✅ 引入 持久化缓存(filesystem cache),二次构建速度提升高达 90% |
Tree Shaking | 支持基础 Tree Shaking,需手动配置 | ✅ 更强的 Tree Shaking + 默认启用 SideEffects,删除无用代码更彻底 |
代码分割 | 需手动配置 | ✅ 自动拆分 chunk,内置 |
模块联邦 | ❌ 不支持 | ✅ 支持 Module Federation,实现微前端、跨应用模块共享 |
资源处理 | 需手动配置 | ✅ 内置 Asset Modules,直接处理图片、字体等资源,无需额外 loader |
缓存机制 | 需额外安装 | ✅ 内置 持久化缓存,自动生效,开发体验大幅提升 |
压缩优化 | 需手动配置 | ✅ 默认使用 terser-webpack-plugin,压缩更快、体积更小 |
现代语法支持 | ❌ 不支持 top-level await、WebAssembly 等 | ✅ 支持 top-level await、WebAssembly、JSON 模块 |
Node.js 兼容性 | ✅ 支持 Node.js 6、8、9 | ❗ 要求 Node.js ≥ 10.13.13,移除旧版本支持 |
配置简化 | ❌ 配置繁琐,需手动优化 | ✅ 默认启用多项优化,配置更简洁,开箱即用 |
总的来说,webpack5相对于webpack4具有更好的构建性能、热更新和tree shaking,并且基于rust的rspack在业界也在迅速扩展,在构建性能上rspack甚至比webpack可以提升百分之八十,并且webpack5可以几乎无痛迁移rspack,故升级webpack对于未来可能迁移到其他更好的构建工具也是一种提前准备。
目前 微前端、组件库、国际化、权限系统……每加一个功能,构建时间就会变得越来越长,特别是很多公司在配合 CI/CD
的逻辑,每构建跑一次可能就得跑 2 分钟,而如果换成 rspack 那么就只要 15 秒上下了,你算算整个团队每天省下多少时间?
二、升级
这里采取的方案是一点点进行升级,保证正常打包运行的情况下进行排查问题,因为之前尝试过直接全部一次性弄好,但是出现了很多预期之外的问题并且也很难定位到具体插件或者代码。
1.准备工作
- Node.js版本至少需要Node.js 10.13.0
- 升级升级
webpack-cli
到最新可用版本 - 将所有使用的插件和加载器升级到最新可用版本
这是经过搜索和验证可以正常运行之后更新的插件加载器等
插件/加载器 | 老版本 | 新版本 |
babel-loader | 8.0.0 | 8.3.0 |
compression-webpack-plugin | 1.1.12 | 6.1.2 |
copy-webpack-plugin | 5.0.4 | 5.1.2 |
html-webpack-plugin": "^" | 3.2.0 | 4.5.2 |
mini-css-extract-plugin | 0.8.0 | 1.6.2 |
optimize-css-assets-webpack-plugin | 5.0.3 | 5.0.8 |
terser-webpack-plugin | 1.4.1 | 4.2.3 |
ts-loader | 6.0.4 | 8.4.0 |
注意我们webpack有三个文件
文件 | 作用 | 何时使用 | 备注 |
webpack.base.config.js | 公共基础配置(loader、alias、插件等) | 始终被合并 | 不区分 dev/prod,只放通用规则 |
webpack.dev.config.js | 开发环境 专用配置 |
| 启用 dev-server、HMR、source-map、代理、懒编译 |
webpack.prod.config.js | 生产环境 专用配置 |
| 开启压缩、source-map、CDN 路径、清理 dist、优化分包 |
2.测试webpack5兼容性
module.exports = {node:{Buffer:false,process:false},
...
}
我们会发现加了上面的代码之后运行会出现process is not defined
,说明验证成功,这里是webpack4的schema检查生效了,webpack5默认为false
3.开始升级
升级中出现的问题很多,需要一个个进行排查测试,这里只列出了常见的方法与问题,有一些简单处理的并没有罗列
升级版本
首先执行命令吧核心的几个进行升级,这是执行升级命令之后的前后版本对比
web merge升级
webpack-merge升级后使用方式改为如下
修改前
const webpackMerge = require("webpack-merge");
修改后
const { merge } = require('webpack-merge');
修改devtool
这里先用tnpm run start测试dev文件,然后根据报错信息修改如下
修改devtool
定义process
webpack5相对于webpack4改变比较大的一点就是不能直接用Buffer
和process
,要改用resolve.fallback
来提供polyfill
所以我们先删除原来文件直接使用的process,然后再用defineplugin进行引用定义
更新caniuse-lite
tnpm update-browserslist-db@latest
更新配置项
把proxy对象改成数组
删除happypack
webpack5已经封装了多线程打包,并且并不兼容happypack,所以我们需要删除happypack
删除happypack,改用webpack原生loader+thread-loader实现多线程打包
这里直接使用thread-loader和babel-loader进行处理即可
兼容性问题
如果Webpack 5 中 thread-loader
和 babel-loader
联合使用时出现不兼容
直接在use配置项中删除一个即可
命名大小写冲突问题
这里是文件名大小写的报错,webpack5禁止两个仅大小写不同的文件,否则会触发竞态条件和文件损坏
后续我尝试全局搜出冲突的源文件
find src -iname '*messagetemplate*' -type f
发现搜不到,说明不是源码目录里面的同名文件
那就直接看dist里面文件,发现也没有同名文件
再扩大范围,在所有文件中搜索大小写不敏感的messagetemplate文件
grep -r -i 'messagetemplate' . --exclude-dir=.git --exclude-dir=node_modules --exclude-dir=dist
出现这样的信息,ai分析后发现是路由懒加载里面出现了两份大小写不同的webpackChunkName
因为两者导入不同,所以直接讲两个都换一个名字就好了
至此运行大致没问题,但是还有很多warning和相关报错
三、处理警告
end值兼容性问题
我们在 Less/CSS 中使用了 align-items: end
或 justify-content: end
等属性值。虽然现代浏览器支持 end
,但为了更好的兼容性(尤其是旧版浏览器),PostCSS 提示改用更通用的 flex-end
v-for缺少key
找到对应的v-for加上key即可
样式引入顺序问题
这些 Warning 全是 mini-css-extract-plugin
报的「样式引入顺序冲突」警告
目前看来样式并没有受到影响,解决方案为统一引入全局样式、避免重复import、合并css chunk等,但是比较繁琐,且不确定到底会不会影响,以前是否也出现过但是不影响,所以这里在插件导入的时候使用ignoreOrder: true
来进行屏蔽警告
四、build升级
进行拆包并且限制包的最大最小体积
开启压缩
五、测试
经过测试工具,启动速度稳定在三秒以内,打包速度在50秒左右
这里还有部分包体积过大需要拆分,还可以进行打包速度优化
但是webpack只能拆包,这里可能需要吧部分例如echarts、tinymce用CDN引入
六、迁移RSpack
启动