由于在进行webpack优化前,翻阅了很多有关webapck优化的文章,所以笔者也想尝试一下用happypack来优化打包时间。
在想要用happypack进行的打包之前,大抵有这两种说法:
1、webpack4中已经默认是多线程打包了,所以happypack打包效果不明显;
2、vue不支持happypack打包,需要设置thread-loader。
但是笔者想了一下,还是试试看把,大不了我只对JS和CSS文件设置happypack。
但是问题又来了,vue-cli内置封装了loader,这个时候我要怎么拿到它的配置,改写里面的loader配置呢。
通过翻阅vue-cli的官方文档我们可以看到以下使用介绍:
configureWebpack
Type: Object | Function
如果这个值是一个对象,则会通过 webpack-merge 合并到最终的配置中。
如果这个值是一个函数,则会接收被解析的配置作为参数。该函数及可以修改配置并不返回任何东西,也可以返回一个被克隆或合并过的配置版本。
为此,笔者特地调试进了vue-cli的源码一探究竟:
流程介绍:
由于我们执行命令行vue-cli-service build,其实是先去node_modules的.bin文件夹下查找相应的可执行文件,.bin下的vue-cli-service会映射到相应的第三方库内的执行文件。
所以我们可以找到这个可执行文件的地址:
/node_modules/@vue/cli-service/bin/vue-cli-service.js
找到了入口,接下来我们想要进入nodejs的调试,在以往的开发中,我们会通过node --inspect app.js的方式启动一个后台服务,然后在谷歌浏览器里进入调试界面(F12选择绿色的那个小按钮)
但是这里却犯了难,由于我们的打包构建是一次执行的,不同于一个后台服务,是实时监听的,服务一直启动着。查阅了一下,如果是普通的nodejs文件想要调试的话,需要通过这样的方式:
node --inspect-brk=9229 app.js
所以,为了强行走进去vue-cli的源码进行调试,可看vue-cli的处理流程,我们需要这样输入以下命令行:
node --inspect-brk=9229 node_modules/@vue/cli-service/bin/vue-cli-service.js build
上面的这个命令行,等价于vue-cli-service build。
通过这样的方式,我们终于走进了vue-cli的源码,看了它的执行流程,你可以在对应的位置打下断点,查看此时的作用域内的变量数据。
可以看到vue-cli源码里的这一段操作,会执行我们传入的函数,判断函数有没有返回值来决定是否要merge进其内部配置的config。
通过这段代码我们可以看出,如果我们configWepack配置为函数,之后通过参数的形式获取到config配置项,本身是一个对象,对象是保留引用的形式,所以如果我们直接对传入的config对象进行修改,就可以实现我们最初的目标!修改vue-cli内置的loader!
当然,除了断点进入里面看配置,刚才也说了,我们可以通过命令行输出为一个output文件查看现有的配置。
这里可以给大家截图看一下vue-cli内部的配置:
可能有点废话了,但是通过断点的方式,我们可以看到vue-cli其实已经对js文件设置了exclude,同时也帮我们设置好了cache-loader,意味着webpack常规的优化方式之一,使用cache-loader缓存它也帮我们做了。
回到最初的起点,我们想要处理的是针对JS和CSS的loader,于是模仿大多数的配置,我进行了以下修改:
configureWebpack:(config)=>{ console.log("webpack config start"); let originCssRuleLoader = config.module.rules[6].oneOf[0].use; let newCssRuleLoader = 'happypack/loader?id=css'; config.module.rules[6].oneOf[0].use = newCssRuleLoader config.module.rules[6].oneOf[1].use = newCssRuleLoader config.module.rules[6].oneOf[2].use = newCssRuleLoader config.module.rules[6].oneOf[3].use = newCssRuleLoader ...//other code }
尝试对css的loader配置进行修改。之后对plugins进行一下配置:
plugins: [ new HappyPack({ id: 'css', threads: 4, loaders: originCssRuleLoader }), ],
本以为这样就OK了,但是很遗憾的告诉大家,报错了...
可以看到报错的内容,是在处理vue文件的时候,出了错误。
如何解决
笔者百度了,也谷歌了,大抵是说happypack不支持vue-loader,同时,根据报错也查了一下处理的方案,通过设置parallel参数,也还是无效。
笔者甚至怀疑是自己的happypack配置不对,于是我把配置原样移植配置到另一个非vue项目中,一切运行正常。
答案:此题无解~
原因分析: