宝哥软件园

基于vue-cli对webpack打包优化实践与探索的深刻理解

编辑:宝哥软件园 来源:互联网 时间:2021-08-19

已经是2019年了。短短三四年时间,webpack打包工具已经成为前端开发的必备工具。一旦面试问题被问到,有哪些优化前端页面的方法?大家可以轻松说出缓存、压缩文件、CSS精灵图、部署CDN等各种方法,但今天不一样了。也许你去面试会问,你知道webpack的包装原理吗,webpack的包装优化方法有哪些?所以,不说的话,作者和webpack的包装优化无关。可能大家都看过类似的优化文章吧~不过笔者还是希望能给大家一些新的启发~1。准备:速度测量和分析包。

既然要优化webpack的打包,就必须提前分析我们的包文件,分析每个模块的大小,分析打包时间主要消耗在哪里。在这里,我们主要需要两个webpack插件,速度测量webpack插件和webpack包分析器。前者用于测量速度,后者用于分析包文件。

特定配置

const SpeedMeasureplugin=require(' speed-measure-web pack-plugin ');const bundlealyzer plugin=require(' web pack-bundle-analyzer ')。bundlealyzer plugin int SMP=new SpeedMeasureplugin({ outputformat : ' human ',});module . exports={ configurewebpack k : SMP . wrap({ plugins :[new web pack。ProvidePlugin({ $: 'zepto ',Zepto: 'zepto ',}),new BundleAnalyzerPlugin(),],optimization : { splitchunks 3360 { cachegroups 3360 { echart : { name : ' chunk-echart ',test :/[ /]node _ modules[ /]echart[ /]/,chunks: 'all ',Priority 3: 10,reuseexist可以看出,Splitchunk是在原项目的初始配置中设置的,这在大型项目中是必须的。毕竟,您不希望您的用户阻止加载5MB JS文件,所以有必要进行代码拆分和惰性加载。

走了很长一段路,让我们来看看这个配置。你需要用smp重新打包配置,因为SpeedMeasurePlugin会在你的其他Plugin对象上包裹一层代理,这样就知道插件的开始和结束时间了~

其次,就像普通的插件一样,BundleAnalyzerplugin可以加载插件数组的后面。

接下来,让我们看一下初始打包时间和包内容分析:

您可以在项目中看到三个更大的包,其中两个是我们的第三方依赖项,比如three.js、lottie、lodash、echarts等等。

2.开始逐步优化

2.1缩小文件搜索和处理的范围

这是webpack优化中的常规操作,基本上是优化模块和文件搜索,减少加载器对不必要模块的处理。但是vue-cli中的loader并没有暴露我们的操作,所以内置的loader处理并不能被我们优化。然而,事实上,vue-cli中的配置项已经优化了加载程序搜索路径。如果您的项目也使用vue-cli,您可以通过下面的命令行检查现有的配置文件。

nbxvue-CLI-service chemicarutput . js可以专门浏览vuecli的官方文档。

resolve : { modules :[path . resolve(_ dirname,' node_modules')],alias : { ' three ' : path . resolve(_ dirname,'。/node _ modules/three/build/three . min . js '),' zepto $ ' : path . resolve(_ _ dirname,'。/node _ modules/zepto/dist/zepto . min . js '),' swiper $ ' : path . resolve(_ _ dirname,'。/node _ modules/swiper/dist/js/swiper . min . js '),' lotie-web $ ' : path . resolve(_ _ dirname,'。/node _ modules/lotte-web/build/player/lotte . min . js '),' lodash $ ' : path . resolve(_ _ dirname,'。/node _ modules/lo dash/lo dash . min . js '),}},module : { noparse :/(vue | vue-router | vuex | vuex-router-sync | three | zepto | wiper | lotch-web | lo dash)$/},指定通过模块搜索第三方模块的路径。打包构造的压缩js文件可以通过alias指定的第三方模块直接找到。模块指定noparse,第三方模块不再依赖分析。优化效果:2s?

可以看到时间减少了两三秒,波动在30s左右,差别不大。

2.2尝试使用happypack

因为在做webpack优化之前看了很多关于webapck优化的文章,所以也想尝试用happypack来优化打包时间。在你想打包之前,有两种说法:

1.webpack4默认已经多线程打包,所以happypack的打包效果不明显;

2.vue不支持happypack打包,所以需要设置线程加载器。

不过想了想,我就试一试。我只为JS和CSS文件设置了happypack。

但问题又来了。vue-cli内置了一个加载程序。如何获取其配置并在内部重写加载器配置?

通过阅读vue-cli的官方文档,我们可以看到以下用法介绍:

configurewebpackktype : object | function如果此值是一个对象,它将通过webpack-merge合并到最终配置中。如果该值是一个函数,它将接收解析后的配置作为参数。函数和可修改的配置不返回任何内容,但也返回克隆或合并的配置版本。

为此,作者专门调试了vue-cli的源代码,发现:

工艺介绍:

当我们执行命令行vue-cli-service构建时,我们实际上转到。bin文件夹中找到相应的可执行文件,并在。bin将被映射到相应第三方库中的可执行文件。

所以我们可以找到这个可执行文件的地址:

/node _ modules/@ vue/CLI-service/bin/vue-CLI-service . js

我们找到了入口,然后我们要进入nodejs的调试。在过去的开发中,我们会通过Node-InspectApp.js启动一个后台服务,然后在Google浏览器中进入调试界面(F12选择绿色小按钮)

但是这里很难,因为我们的包构造只执行一次,不同于后台服务,是实时监控的,服务总是启动的。查找一下,如果是普通的nodejs文件想要调试,需要这样调试:

Node-inspect-brk=9229app.js因此,为了强行进入vue-cli的源代码进行调试,我们可以看一下vue-cli的处理流程,需要像这样输入如下命令行:

node-inspect-brk=9229 node _ modules/@ vue/CLI-service/bin/vue-CLI-service . jsbuild的上述命令行相当于vue-cli-service build。

就这样,我们终于进入了vue-cli的源代码,看完它的执行流程,就可以在对应的位置破断点,查看此时作用域内的变量数据。

您可以在vue-cli的源代码中看到这个操作,它将执行我们传入的函数,并判断该函数是否有返回值来决定是否合并到其内部配置配置中。

从这段代码中我们可以看到,如果我们把configWepack配置成一个函数,然后以参数的形式得到config配置项,它本身就是一个对象,而这个对象是以保留引用的形式存在的,所以如果我们直接修改传入的config对象,就可以达到我们最初的目的!修改vue-cli内置的加载程序!

当然,除了输入断点查看配置之外,正如我刚才所说,我们还可以通过命令行输出将现有的配置作为输出文件查看。

这里你可以截图看看vue-cli的内部配置:

可能有点废话,但是通过断点,我们可以看到vue-cli实际上已经为js文件设置了exclude,也为我们设置了cache-loader,这意味着webpack的常规优化方法之一,cache-loader也对我们有帮助。

回到最初的起点,我们要处理JS和CSS的加载器,所以我模仿了大部分的配置,做了如下修改:

configureWebpack:(配置)={ console . log(' web pack config start ');让originssruleloader=config . module . rules[6]。[0]之一。使用;让new cssrruleloader=' happy pack/loader?id=CSS ';config.module.rules[6]。[0]之一。use=newCssRuleLoader config . module . rules[6]。[1]之一。use=newCssRuleLoader config . module . rules[6]。[2]之一。use=newsruleloader config . module . rules[6]。[3]之一。use=newssruleloader.//othercode}试图修改css的加载程序配置。然后配置插件:

插件:【新快乐包({ ID :‘CSS’,线程3360 4,加载器: Origins Ruleloader}),】,我以为还可以,但是很遗憾的告诉你,我报告了一个错误。

您可以看到错误报告的内容,即在处理vue文件时发生了错误。

如何解决

作者百度,也是谷歌。一般来说,happypack不支持vue-loader。同时,根据错误报告,他还查看了处理方案。通过设置并行参数,它仍然无效。

我甚至怀疑我的happypack配置是错误的,所以我将配置原样移植到了另一个非vue项目中,一切正常。回答:这个问题没有解决办法~

原因分析:

vue文件将包含css,因此vue-loader将从中提取CSS,并将其交给其他加载器进行处理。vue-loader-plugin将告诉其他加载程序通过向vue文件附加查询字符串来处理这个文件。这是什么意思?我们的vue-loader通知其他加载器处理文件,但是加载器配置已经重写为happypack,vue与happypack不兼容,最终导致报错。很抱歉告诉你vue-cli无法访问快乐包。

(注:这部分主要是作者在webpack优化过程中的探索。虽然最终无法很好的优化自己的webpack打包,但是在探索的过程中可以学到很多东西,包括vue-cli对配置对象的处理。如何调试公共文件nodejs代码?vue-loader中vue文件的处理流程是怎样的?vue加载插件为我们做了什么?而这些都是要慢慢读,慢慢踩坑才能明白的~)

2.3使用dllplugin

像大多数webpack优化教程一样,作者也尝试使用dllplugin进行优化。这个插件的本质就是把常用的第三方模块提取出来,单独打包成一个文件包,然后插入到我们的html页面中,这样以后每次打包的时候就不需要处理第三方模块了。毕竟有几千行第三方模块。

工艺介绍:

1.配置webpack.dll.js为第三方库打包

2.在vue.config.js中配置插件

3.dll打包的js文件被引入到html中。(一般部署CDN)

因为项目中有很多大型的第三方库,比如three、echart等。作者做了如下配置:(webpack.dll.js)

const web pack=require(' web pack ')const path=require(' path ')const HTMl webpackkplugin=require(' HTMl-web pack-plugin ');module . exports={ entry : { vuebundle :[' vue ',' vue-router ',' vuex ',],utils:[ 'lodash ',' swiper ',' lotie-web ',' three ',],echart 3360[' echart/lib/echart ',' echart/lib/chart/bar ',' echart/lib/chart/line ',' echart/lib/component/title ',},/static/'),filename: '[name].dll.js ',library: '[name]_library' },plugins: [ new webpack。DllPlugin({ path : path . join(_ _ dirname,' build ',[name]-manifest.json '),name:' [name] _ library'})])根据不同库的大小进行划分,分三个包进行打包。为什么不把它们打包成一个包裹呢?一个包裹太大了。您不希望您的用户加载一个大的JS包并阻止它,这将影响页面性能。

下面是vue.config.js的配置:

plugins: [新webpack。ProvidePlugin({ $: 'zepto ',Zepto: 'zepto ',}),新的DllReferencePlugin({ manifest : require(')。/build/echart-manifest . JSON '),}),新的DllReferencePlugin({ manifest : require ')。/build/utils-manifest.json '),}),新的dllreference插件({manifest : require('。/build/vuebundle-manifest.json '),}),新的bundle analyzerplugin(),]引入了DllPlugin。然后配置HTML:

(由于没有将DLL打包的js文件上传到CDN,所以只能在本地设置一个节点服务器来返回静态资源。)

body div id='app'/div!将自动注入内置文件-脚本类型='text/javascript ' src=' http :http://localhost :3000/echart . dll . js '/脚本脚本类型=' text/JavaScript ' src=' http :http://localhost 33603000/utils . dll . js '/脚本类型=' text/JavaScript ' src=' http :00/utils . dll . js '/脚本类型=' text/JavaScript '

舒服~

优化结果:

由于没有大型第三方库,时间控制在20s左右。优化相对明显~

3.优化探索总结

优化到这,基本就结束了。

常用的优化webpack的方法,比如优化路径搜索、设置缓存、happypack、dllplugin等,都是通过vue-cli为我们做的,但是happypack因为和vue不兼容而无法访问,dllplugin通过单独提取第三方库实现了明显的优化。当然,作者也试图在一些项目中消除无用的代码,但这也是无痛的。

webpack优化方法概述:

1.优化模块找到路径

2.消除不必要和无用的模块

3.设置缓存:缓存加载程序(缓存目录/缓存加载程序)的执行结果

4.设置多线程:HappyPack/线程加载器

5.dllplugin提取第三方库

当然,这是为了发展而优化。如果是部署优化呢?我们可以设置splitchunk、按需加载、部署CDN等。这里就不展开了。

最后的

希望大家都能从这篇文章中有所收获~ webpack已经成为前端学生必备的技能了~有时间的话可以深入研究一下webpack的配置和原理,也会有所收获!谢谢观看~

以上就是本文的全部内容。希望对大家的学习有帮助,支持我们。

更多资讯
游戏推荐
更多+