为什么同样的配置别人可以提高效率,你反而降低了

背景

笔者最近发现本地打包太慢,大概需要3分钟左右,于是在网上找了百度了下 发现就是2个点

  • dll
  • hard-source-webpack-plugin

看了下文章就说用了hard-source-webpack-plugin之后能提升 90% 的构建速度,于是乎我满心欢喜的用上了了,发现第一次构建3分半,,第二次 还是3分半 ,于是乎我就好奇,为什么呢??

由于公司的内网不能上掘金,也不能发表文章,所以笔者是在家里研究这个问题的,项目也是网上随便找的。所以实际的数据可能和真正的公司的项目有偏差,但是此文章的目的只是引导大家遇到问题的时候如何去思考以及解决他

本文章分析的源码是基于@vue/cli 4.5.11创建的都是默认配置,代码不重要,重要的是分析的过程

分析

一直以来计时都是用手机计时,那么我是不是需要一个工具来帮我计算这个时间,可以用speed-measure-webpack-plugin但是时间信息不是在最后一行输出,为了方便看时间,那么就自己写一个计算打包时间的webpack插件CountTimePlugin

统计webpack打包时间插件CountTimePlugin

这个插件的编写逻辑就是利用webpackstatsendTimestartTime做一个减法就出来了打包时间

// CountTimePlugin.js
module.exports =  class CountTimePlugin {
  constructor() {}

  apply(compiler) {
    compiler.hooks.done.tap("ConsoleTime", stats => {
      const times = stats.endTime - stats.startTime;
      const minute = Math.floor(times / 1000 / 60);
      const second = Math.floor(times / 1000 - minute * 60);
      setTimeout(() => {
        console.log(
          "the build time:\n" + minute + " minute , " + second + " second \n"
        );
      },2000)
    });
  }
}
复制代码

使用统计时间插件

连续打了2次包发现时间都是27 秒左右,查看了一下speed-measure-webpack-plugin打包的日志都是如下

image.png

首先2次打包之间我是没有对代码进行修改的,那么cache-loader没有生效?

检查是否启用了cache-loader

使用 vue inspect > projectConfig.txt 查看这个配置文件我们可以发现.vue文件和test: /\.m?jsx?$/,的文件都是用cache-loader

image.png

这个时候思路就有点乱了有使用cache-loader为什么没有换成呢?这个时候脑袋中突然想到每次打包都有hash难不成不一样?这个想法一下子就好像打开了通往成功的大门

检查cache-loader的hash

我有一次的再命令行输入vue inspect > projectConfig2.txt

image.png

对比了一下 发现cacheIdentifier 真的不一样,为什么呢?

定位问题

如何调试

调试的方法有很多,比如装一个debugger-for-chrome,但是笔者还是喜欢用编辑器调试代码,控制台新建一个JavaScript Debug Terminal
输入

node ./node_modules/@vue/cli-service/bin/vue-cli-service.js build
复制代码

找到cacheIdentifier在哪里生成的

我们的入口文件是node_modules/@vue/cli-service/bin/vue-cli-service.js

// 刚开始是一个构造器,第32行调用了一个生成插件的方法
this.plugins = this.resolvePlugins(plugins, useBuiltIn)

// 142行  
resolvePlugins(){
    const idToPlugin = id => ({
      id: id.replace(/^.\//, 'built-in:'),
      apply: require(id)
    })

    let plugins

    const builtInPlugins = [
      './commands/serve',
      './commands/build',
      './commands/inspect',
      './commands/help',
      // config plugins are order sensitive
      './config/base',
      './config/css',
      './config/prod',
      './config/app'
    ].map(idToPlugin)
    
    //... 省略
    // 看了下builtInPlugins数组中的文件,其中./config/base 就是生成vue-loader cache-loader配置的地方
    
    //  ctrl+f 搜一下plugins 就能看到 init方法中有使用
    
      // apply plugins.
    this.plugins.forEach(({ id, apply }) => {
      if (this.pluginsToSkip.has(id)) return
      apply(new PluginAPI(id, this), this.projectOptions)
    })
    
    //  再打断点可以知道 执行的是node_modules/@vue/cli-service/lib/commands/build/index.js的方法
}
复制代码

我们在 node_modules/@vue/cli-service/lib/commands/build/index.js 第三个参数中增加断点得知,最后调用的是
node_modules/@vue/cli-service/lib/commands/build/resolveAppConfig.js的方法,

image.png

image.png

到这里终于回去了。我们回到 service.js 再继续断点可以跳转到node_modules/@vue/cli-service/lib/PluginAPI.jsgenCacheConfig方法

调试genCacheConfig

image.png

通过前面的步骤我们可以得知,我们总算找到了生成cacheIdentifier的地方就是在genCacheConfig

const cacheIdentifier = hash(variables)
复制代码

通过这段代码可以知道 唯一的变量就是variables

 const variables = {
      partialIdentifier,
      'cli-service': require('../package.json').version,
      'cache-loader': require('cache-loader/package.json').version,
      env: process.env.NODE_ENV,
      test: !!process.env.VUE_CLI_TEST,
      config: [
        fmtFunc(this.service.projectOptions.chainWebpack),
        fmtFunc(this.service.projectOptions.configureWebpack)
      ]
    }
复制代码

于是我们看一下我们项目的webpack配置

const childProcess = require('child_process')
// 分支名 因为平安都是标装机自带全局的git工具
const branch = childProcess.execSync('git rev-parse --abbrev-ref HEAD')


configureWebpack: {
    plugins: [
      new CountTimePlugin(),
      new webpack.BannerPlugin(`分支名: ${branch}, 打包时间:  ${new Date().toLocaleString()}`),
      new HardSourceWebpackPlugin()
    ],
  },
复制代码

就可以发现 我们的项目用了一个bannerPlugin,因为项目都是本地打包,会有多个版本并行,然后只有一个环境,会发生抢环境的问题,于是我就把所有的静态资源,加一个日志 把git分支名,以及打包时间打包到静态资源中了,这样可以解决开发人员快速辨别当前的测试环境的代码是哪个分支的,没想到随手增加的打包时间反而导致了hard-source-webpack-plugin不起作用,找到这个原因之后,处理起来就很简单了。就把打包时间去掉就好了。

效果

第一次打包时间如下:
image.png
第二次打包时间如下:

image.png

结语

经过这一次的失误之后还是让自己成长许多,并不是每一次百度好的一些优化配置都适用于自身系统,可能自身系统本身就有一些有害的配置会使得其他人的优化做无用功

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享