阅读 921

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,选择第一个就可以大功告成了:
image.png
在ch点击如下按钮就可以打开vscode对应的组件了
image.png

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 ..." 复制代码

image.png
可以猜测这是shelljs的问题,我们更新一下shelljs后报错消失

前后对比

所有对比都在文件没有任何变动的情况下,图一为优化后,图二为优化前
首次打包缩短20s
二次打包缩短60s
首次构建缩短100s
二次构建缩短80s

首次打包

image.png
image.png

二次打包

image.png
image.png

首次构建

image.png
image.png

二次构建

image.png
image.png


作者:隐身ing
链接:https://juejin.cn/post/7020692335696707620


文章分类
后端
文章标签
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐