webpack5升级指南,webpack5真香!
背景
由于公司的后台项目比较大,构建时间非常久,觉得很浪费时间,就起了优化的心思。看了一些webpack优化的文章,大部分都提到了webpack5的持久性缓存大大提升了构建速度,而且官方也说了尽可能长时间地保持在v5版本。所以!干起来吧!
官方给出的这个版本重点在于以下几点。
尝试用持久性缓存来提高构建性能。
尝试用更好的算法和默认值来改进长期缓存。
尝试用更好的 Tree Shaking 和代码生成来改善包大小。
尝试改善与网络平台的兼容性。
尝试在不引入任何破坏性变化的情况下,清理那些在实现 v4 功能时处于奇怪状态的内部结构。
试图通过现在引入突破性的变化来为未来的功能做准备,使其能够尽可能长时间地保持在 v5 版本上
本次升级基于webpack4.3.0 升级至webpack5.54.0 再提一句,本文完全基于我司的配置进行优化,也仅代表个人愚见(webpack小白),文内也留了一些问题,望各位大佬解惑,不甚感激~
建议在开干之前也先阅读一下迁移指南
升级webpack
首先先将webpack工具及一些基础包升级到最新版本
npm install --save-dev webpack-cli@latest webpack@latest webpack-merge@latest webpack-dev-server@latest 复制代码
Webpack 5 对 Node.js 的版本要求至少是 10.13.0 (LTS),因此,如果你还在使用旧版本的 Node.js,请升级它们。
loader
file-loader & url-loader
webpack5内置了资源模块的处理,可以替代以往的file-loader,url-loader,raw-loader,所以可以卸载这几个loader,直接内置处理
{ test: /\.png$/, loader: 'url-loader', options: { limit: 10 * 1024, name: 'images/[name].[ext]' } } 复制代码
上方配置可以看出,如果图片大于10kb将会启用file-loader将文件单独导出,资源模块配置如下
{ test: /\.png$/, type: 'asset', parser: { dataUrlCondition: { maxSize: 10 * 1024 // 10kb } }, generator: { filename: 'images/[name][ext]' } } 复制代码
type: asset 在导出一个 data URI 和发送一个单独的文件之间自动选择。之前通过使用 url-loader,并且配置资源体积限制实现。
parser:
如果 Rule.type 的值为 asset,那么 Rules.parser 选项可能是一个对象或一个函数,其作用可能是将文件内容编码为 Base64,还可能是将其当做单独文件 emit 到输出目录。
如果 Rule.type 的值为 asset 或 asset/inline,那么 Rule.generator 选项可能是一个描述模块源编码方式的对象,还可能是一个通过自定义算法对模块源代码进行编码的函数
dataUrlCondition:如果一个模块源码大小小于 maxSize,那么模块会被作为一个 Base64 编码的字符串注入到包中, 否则模块文件会被生成到输出的目标目录中
generator.filename:控制文件输出
vue-loader
之前vue-loader用的是15.9.1版本的,然后一直编译不成功,然后也找了很多资料,都挺尴尬。然后猜测是不是不兼容webpack5,然后升级了一下vue-loader版本,确实编译成功
15.9.1升级至15.9.8,升级完后发现页面内有一处完成不兼容的报错,目前是手动修改的。
<script> export default { data() { return { // 通过webpack.Defineplugin全局注入的常量,直接报页面编译错误 DOMIN_URL, // 修改为 "DOMIN_URL": DOMIN_URL } } } </script> 复制代码
sass-loader
之前项目中sass-loader依赖Node Sass,非常耗费时间,官方更推荐使用Dart Sass,至于为什么选择Dart Sass可以看看官方的解释,大致就是更快,更容易安装等等
npm install --save-dev sass 复制代码
重新编译后有如下警告,原因是因为Dart Sass 2.0.0以后使用math.div替代/,但是这里的警告涉及到element-ui包,只能手动降级到Dart Sass 1.32.13版本,重新编译警告消失
DEPRECATION WARNING: Using / for division is deprecated and will be removed in Dart Sass 2.0.0. Recommendation: math.div($--tooltip-arrow-size, 2) 复制代码
babel-loader
从一篇文章里看到esbuild可以大大提高构建速度,然后就起了试一试的心态,效果简直惊人,构建速度提升20s+
注意: 官方文档中提到针对大部分语法esbuild只支持转换到es6,因此只适合在开发环境使用,生产环境不建议使用
// dev module: { rules: [ { test: /\.js$/, use: [ { loader: 'esbuild-loader', options: { loader: 'js', target: 'es2015', } } ], exclude: /node_modules/, include: resolve('src') } ] } 复制代码
cache-loader & dllplugin
webpack5之前优化大部分依赖cache-loader对一些耗时比较大的地方增加缓存,或者依赖dllplugin减少打包内容,使构建加速。
webpack5提供了开箱即用的持久化缓存,引入缓存后,基于我的项目首次构建时间将增加 10%,二次构建时间大致缩小了百分之85%
module.exports = { cache: { type: 'filesystem', // 启用持久化缓存 cacheDirectory: resolve('.temp_cache'), // 缓存文件存放的位置 buildDependencies: { // 缓存失效的配置 config: [__filename] } } } 复制代码
plugins
html-webpack-plugin
有报错,就直接升级到最新版本就可以了
npm i --save-dev html-webpack-plugin@latest 复制代码
clean-webpack-plugin
output多了一个clean参数,在生成文件之前清空 output 目录,所以加上这个参数后就可以把插件去掉啦
optimize-css-assets-webpack-plugin
官方提示我们对于webpack5或者更高的版本请改用css-minimizer-webpack-plugin,使用新的plugin后打包发现少了400kb左右
给个官网的例子
const MiniCssExtractPlugin = require("mini-css-extract-plugin"); const CssMinimizerPlugin = require("css-minimizer-webpack-plugin"); module.exports = { module: { rules: [ { test: /.s?css$/, use: [MiniCssExtractPlugin.loader, "css-loader", "sass-loader"], }, ], }, optimization: { minimizer: [ // 在 webpack@5 中,你可以使用 `...` 语法来扩展现有的 minimizer(即 `terser-webpack-plugin`) '...', new CssMinimizerPlugin(), ], }, plugins: [new MiniCssExtractPlugin()], }; 复制代码
devServer
原先的配置如下
devServer: { ..., // 一些没有改变的配置,类似hot,open等 quiet: true, overlay: true, disableHostCheck: true, clientLogLevel: 'warning' // 控制台提示信息级别是 warning 以上 } 复制代码
quiet:移除,官方迁移文章建议可以在infrastructrueLogging中修改,这部分其实没看明白,目前直接把infrastructrueLogging.level设置为info,显示错误告警与信息,但是又用了friendly-errors-webpack-plugin,导致错误告警显示2次,直接用none的话又没有基础设施日志,求解答!
overlay:移至client中
clientLogLevel:移至client中,更改为logging属性
disableHostCheck:更改为allowedHosts,可以自行增加白名单
修改后配置如下
devServer: { client: { overlay: { // 只显示错误信息 errors: true, warnings: false, }, logging: 'warn' // 控制台只显示warn以上信息 }, allowedHosts: 'all' }, infrastructrueLogging: { level: 'info' } 复制代码
其它
devtool一键打开vscode源码
首先安装launch-editor-middleware
npm install --save-dev launch-editor-middleware 复制代码
在webpack.dev.js里配置
然后把编辑器加入到环境变量里
以vscode为例,Command + Shift + P打开Command Palette,输入shell command,选择第一个就可以大功告成了:
在ch点击如下按钮就可以打开vscode对应的组件了
shelljs
我目前用的node版本是14.17.1的,跑起来后发现有一堆警告,虽然不影响运行,但是终究很难受,所以还是解决一下
Warning: Accessing non-existent property 'cd' of module exports inside circular dependency (node:21085) Warning: Accessing non-existent property 'chmod' of module exports inside circular dependency (node:21085) Warning: Accessing non-existent property 'cp' of module exports inside circular dependency 复制代码
在package.json run的命令行后面加上下方命令查看node报错的具体信息
"test": "cross-env NODE_OPTIONS=--trace-warnings ..." 复制代码
可以猜测这是shelljs的问题,我们更新一下shelljs后报错消失
前后对比
所有对比都在文件没有任何变动的情况下,图一为优化后,图二为优化前
首次打包缩短20s
二次打包缩短60s
首次构建缩短100s
二次构建缩短80s
首次打包
二次打包
首次构建
二次构建
作者:隐身ing
链接:https://juejin.cn/post/7020692335696707620