乐趣区

关于前端:Vue-vue-2x项目生产编译优化缩短编译时间-基于vuecli3-webpack-4

状况阐明:前端我的项目,技术框架是 vue 2.x + element ui + highcharts,平台内容是基金股票相干(基金行情、基金产品详情、基金经理详情、尽调报告;股票行情;模仿组合,在售组合等)目前我的项目曾经超过 11 万行代码,开发编译 (本地) 须要 1min 左右,生产编译 (本地) 均匀须要 17min 左右。因为是 docker 容器化部署,每次上线都要跑流水线编译公布,线上编译的 CPU 可能不如本地,跑一次流水线的工夫在 60-90min 不等,其中编译工夫大多在 40-60min,慢!!

这周抽空钻研一下如何进步编译速度。
(同步更新到本人的语雀,文章、代码的款式更好看点
能够移步 https://www.yuque.com/diracke…)

翻阅各类文章材料,看下来思路有三个:
1、loader 多过程 2、压缩工具多过程 3、dllPlugin

在这里先说各条思路实际下来的论断
1、loader 多过程 – 失败,做无用功
(被讲的最多的是利用 happypack 开启多过程 Loader 转换,次要用来晋升 babel 的速度)
vue/cli3 中 自带了 thread-loader (== happypack) 用于多过程解决,仅在生产环境凋谢。

2、应用 webpack-parallel-uglify-plugin 加强代码压缩(uglify 多过程)–uglifyJs 自带多过程,我都不晓得这个 webpack-parallel-uglify-plugin 的作者在干啥,再加上晋升无限,没摸索
“自带的 js 压缩插件是单线程的,而该插件会开启多个子过程,将压缩工作分给多个子过程去实现,每个子过程还是通过 uglifyjs 去压缩代码,无非就是并行处理压缩,效率更高。”
下面这段话,我见了十分多,但调研发现,webpack 官网的 uglifyjs 本身有多过程选项,且 uglify 在我的编译 16min 中仅占一分钟,所以没有往下走,这条思路是否正确意义不大,晋升无限。
(调研工夫 2021 年 12 月 16 日,npm 上看,uglifyjs 最初一个版本 v2.2.0 是两年前公布的,而 webpack-parallel-uglify-plugin 最初一个版本 v2.0.0 是一年前公布的)

3、dllPlugin 提取出咱们罕用的第三方模块,独自打成一个文件包,之后插入到咱们的 html 页面中。这样咱们当前每次打包,都不须要针对第三方模块进行解决,毕竟第三方模块动辄成千上万行。
第一次读到这句话的时候,我认为 dll 的编译会花很多工夫,之后因为应用了 dll 的编译产物,所以每次编译的时候就节俭了共用 dll 的编译工夫。(首次残缺编译的时候,别离编译出 dll 文件和我的项目文件。之后再编译的时候只须要编译我的项目文件,不须要编译 dll 文件,节俭的是编译第三方库的工夫,然而对 docker 这样的容器化部署,dll 和 cache 都没有用,因为每次流水线都是从新编译的过程。因而还想到了走 3 的思路,把第三方库独自打包,且起一个服务,提供 dll.js 文件的思路)(同一份代码,两条流水线,两份编译产物)
实际上,dll 文件的编译只须要 1min 左右,而插入 dll 之后,我的项目编译的工夫变成了 6min 左右(也就是说整个编译工夫变成了 7min 左右)。
dll 的形式节省时间的起因是它缩小了拆解第三方库再打包到各个 chunk 的工夫。这是 dll 形式最大的意义所在。
艰深来讲,dll 的形式就是在 vue 我的项目中,通过在 App.vue 中通过 <script type=”text/javascript” src=”http://url”></script> 的形式引入打包的第三方库 dll.js 文件。
<body>

<div id="app"></div>
<script type="text/javascript" src="url/dll01.dll.js"></script>
<script type="text/javascript" src="url/dll02.dll.js"></script>
<!-- ... 多个 dll 文件引入 -->

</body>

讲过程之前先说须要用到的量化、剖析打包工夫的工具
speed-measure-webpack-plugin(SMP)
这个包能够统计编译的总工夫,以及测量各个插件和 loader 在编译过程中破费的工夫。

装置过程参考这篇 blog
《Vue-cli 中 Webpack 配置优化(一)》留神区别 vue cli2 vue cli 3
https://www.cnblogs.com/zhuro…

本来我的项目编译工夫统计

剖析发现各种 loader 以及 uglifyJs 占用工夫不多,16min 外面的大头应该是把文件编译成 chunk.js 的过程。
退出 dll 之后 dll 的编译工夫在 1min 左右,我的项目打包工夫变为了 6min

DLL 应用过程

1、装置依赖项
webpack
clean-webpack-plugin(用于在构建之前清空构建文件夹)
add-asset-html-webpack-plugin(主动插入 dll.js 的援用链接)

2、在 vue.config.js 同级目录下新建 webpack.dll.config.js 文件

3、在 webpack.dll.config.js 中,引入依赖项,写配置(写须要抽离的第三方库,打包成独自的 js 文件,留神看 entry 外面的配置,这个写法会打包出 4 个 dll.js 文件)

4、在 package.json 写一个编译命令 “build:dll”: “webpack –config webpack.dll.config.js”

5、运行编译命令 npm run build:dll,失去 dll 文件

开展 /dll 的目录,能够看到以 vuebundle、vendor、ui、util 结尾的 dll.js 文件和以 vuebundle、vendor、ui、util 结尾的 manifest.json 文件。

6、改写 vue.config.js,使得 npm run build 的时候不编译曾经进入 dll.js 的第三方库文件,同时在编译的时候主动插入援用 dll 的 <script src=”http://url”></script> 标签。

dllNameArr 数组外面的各项,要和 webpack.dll.config.js 里 entry 的各项一一对应。

另外 chainWebpack 中,要减少配置项,在生产环境编译的时候开启 dllReference。

在第 6 步的时候要留神,援用 dll 文件夹的门路是什么。
(如果报错,就要批改 vue.config.js 中 publicPath,或者批改 webpack.dll.config.js 中 output 的 path)

7、最初 npm run build,功败垂成。

容器化部署还须要去改流水线脚本,与本文无关,完结!

— 附参考文章材料
2019 年 08 月 14 日 21:19《vue 我的项目打包优化之 happypack》
https://juejin.cn/post/684490…
这是个老式的 webpack.base.conf.js 配置形式
文章说 HappyPack 对 file-loader、url-loader 反对的不敌对
文章说 HappyPack 对 less-loader、sass-loader、stylus-loader 反对的不敌对

2017-08-29 happypack compatibility list
https://github.com/amireh/hap…
这里 happypack 反对列表里 有 sass-loader 和 css-loader 然而很可怜,vue-loader 和 sass-loader 以及 css-loader 不兼容

2021-01-06 16:47:12《利用 webpack-chain 配置 happypack 和 DllReferencePlugin》
https://blog.csdn.net/qq_3467…
这个文章提到
须要用 const hRule = config.module.rule(‘js’)的形式显示定义,而不要间接链式调用。
const hRule = config.module.rule(‘js’) 再进行过滤和匹配,如果间接在 config.module.rule(‘js’).test(/.js$/).include.add(resolve(‘src’)) .end()是不对的,有可能是不报错又不失效的,有的是打包正式环境会报错。

2019-10-13《基于 vue-cli 的 webpack 打包优化实际及摸索》
https://segmentfault.com/a/11…
因为 vue 文件中会含有 CSS,所以 vue-loader 会提取出其中的 css,交给其余 loader 解决,vue-loader-plugin 会通过在 vue 文件前面加上查问字符串来通知其余 loader,针对这个文件要做解决。意味着什么呢?咱们的 vue-loader 在解决文件的时候,告诉其余 loader 解决,然而此时的 loader 配置曾经被咱们改写成了 happypack,而 vue 又与 happypack 不兼容,最终导致了报错。很遗憾的通知大家,vue-cli 接入 happypack– 失败。

2019-10-08《vuecli3 怎么应用 happypack》
https://segmentfault.com/q/10…
答复 1 从 webpack4 发表之后,happypack 曾经不保护了,退出历史舞台了,有新的 thread-loader 代替。另外,如果你只是单纯地想放慢编译打包速度的话,不如上 dllplugin,这个比 thread-loader 快。
答复 2 vuecli3 不须要应用 happypack,vuecli3 脚手架默认采纳了 thread-loader(与 happypack 作用雷同)放慢编译。(仅生产环境)

2020-03-31《Vue-cli 中 Webpack 配置优化(一)》
https://www.cnblogs.com/zhuro…
量化、剖析打包工夫的插件 SMP 区别 vue cli2 vue cli 3

2018-09-03《[Vue CLI 3] 配置解析之 parallel》
https://segmentfault.com/a/11…
(这一篇有很多同名文章,也有一篇全英的文章找不到发表日期
https://titanwolf.org/Network…
不晓得谁抄谁)
通过测试得出结论:
thread-loader 的开启条件,开启后的作用和上文中的表述一样
(和上面这段代码的成果一样)
const useThreads = process.env.NODE_ENV === ‘production’ && options.parallel;
if (useThreads) {
jsRule
.use(‘thread-loader’)
.loader(‘thread-loader’)
}

然而我没有在 vue 我的项目 以及 @vue/cli 中找到这段源码。
最相似的代码出自
https://gist.github.com/imanh…
vue-cli-apollo-webpack-config.js 这里的代码
如果有源码出处,请指教。

注: 不须要在 vue.config.js 中对 parallel 进行手动配置
如果在某个我的项目外面看到 vue.config.js 配置了:
parallel: require(‘os’).cpus().length > 1
删掉它。无用,多余。

2020-11-22《初尝 Vue3,通过 DllPlugin 和 DllReferencePlugin 优化打包》
https://blog.csdn.net/vipshop…

退出移动版