一次vue2项目打包构建优化过程

记一次vue2项目构建优化过程。

项目基本情况

项目是一个vue2+webpack4的管理平台,

接下来看一下项目的打包耗时情况和产物依赖情况

耗时情况

首先使用SpeedMeasurePlugin来看一下项目的构建过程中各个阶段的耗时情况。

 
  

ini

复制代码

const SpeedMeasurePlugin = require("speed-measure-webpack-plugin"); const smp = new SpeedMeasurePlugin(); ​ module.exports = {  configureWebpack: smp.wrap({    // 在这里配置原本的Webpack配置    // 可以定义entry、output、module等配置 }) };

使用SpeedMeasurePlugin分析打包情况,项目总体耗时43s,其中有一些loader耗时过长,会帮我们标红,尤其是vue-loadersass-loaderpostcss-loader耗时过长,后续可以考虑使用缓存,并行处理使用thread-loader来优化。

产出依赖

webpack-bundle-analyzer使用这个插件,可以帮助分析项目的构建结果,以识别过大的模块、重复的依赖和不必要的代码。一旦你生成了可视化分析界面,可以按照以下方式来进行分析:

  1. 查看模块大小

    • 通过可视化界面,可以看到每个模块的大小。这可以帮助识别哪些模块尺寸过大,从而考虑是否需要对其进行优化,例如拆分代码、按需加载等。
  2. 检查重复的依赖

    • 可以查看依赖关系图,识别是否有重复的依赖被打包进了多个bundle中。这可能意味着某些依赖被重复引入,可以考虑通过Webpack的代码拆分功能或其他优化策略来避免重复打包。
  3. 识别不必要的代码

    • 通过分析模块之间的依赖关系,可以发现是否有一些不必要的代码被打包进了bundle中。这可能是因为某些模块被错误引入,或者存在无用的代码。通过分析依赖关系,可以识别并清理这些不必要的代码。
  4. 查看模块间的依赖关系

    • 了解模块之间的依赖关系可以帮助你优化代码拆分策略,以减少不必要的依赖关系,提高构建性能。

首先安装插件npm install --save-dev webpack-bundle-analyzer

 
  

ini

复制代码

const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; ​ module.exports = { configureWebpack: {    plugins: [      new BundleAnalyzerPlugin()   ] } }

浏览器打开了一个http://127.0.0.1:8888/的页面,页面上就是我们项目的产物依赖情况,

发现比较大的产物就是echarts、element-ui.common,js和wangeditor,这个后续可以考虑按需加载、使用CDN引入和压缩。

开始优化
升级webpack

为啥把webpack升级放到第一个,个人喜好吧,觉得这个升级可能是性能提升最大的一个。

首先下载一个npm-check,查看当前npm依赖包的情况,有些可能会出现npm证书的情况,比如我的旧项目,做法也比较简单,切换到最新的淘宝镜像源,然后删掉node_modules,重新安装即可。

运行npx npm-check就可以了,或者也可以全局安装。

npm-check是一个用于检查项目中npm依赖包是否有更新版本的工具。通过运行npm-check命令,可以列出当前项目中已安装的npm包,并显示它们是否有可用的更新版本。这样可以帮助开发者及时了解项目依赖包的更新情况,及时更新以确保项目的安全性和稳定性。

会出现这么几种情况,根据具体的保存信息自行调整。 MAJOR UP 有一个或多个主要版本更新可用,建议及时更新以获取最新功能和修复bug。 NOTUSED 表示该依赖包未被项目使用,可以考虑移除以减少项目的依赖项数量。

PKG ERR!表示在检查依赖包时出现错误,可能是由于网络问题或依赖包本身存在问题导致的。 MISSING!表示在项目中缺少某个依赖包,可能会影响项目的正常运行,需要及时安装该依赖包。

接下来使用npm-check-updates 来检查依赖库可更新的版本

运行npx npm-check-updates即可

npm-check-updates是一个npm包,它可以帮助你检查当前项目中的npm依赖包是否有可用的更新版本。通过运行npm-check-updates命令,你可以快速了解哪些依赖包可以更新到最新版本,以便及时更新你的项目依赖,保持项目的安全性和稳定性。这个工具可以帮助你轻松地管理npm依赖版本,提高项目的维护效率。npm check-updates包含以下常用命令:

  1. npm-check-updates:检查当前项目中哪些npm包可以更新到最新版本。
  2. npm-check-updates -u:将package.json文件中的依赖版本号更新为最新版本。
  3. npm-check-updates -a:显示所有可用的更新,包括主要版本更新。
  4. npm-check-updates -g:检查全局安装的npm包是否有可用更新。
  5. npm-check-updates -f :根据提供的过滤器筛选要检查的依赖包。
  6. npm-check-updates -x :排除特定的依赖包不进行检查。

npm-check-updates -p :指定要使用的包管理器,如npm或yarn。

运行npx npm-check-updates -u在package.json中的依赖便被更新了

因为这里只关注webpack及相关依赖,不涉及vue,于是将vue-router,vuex,vue-template-compiler还原。

运行npm i再重新安装这些依赖即可。

安装完毕后,运行vue inspect > webpack-config.js重新查看配置情况

报错

Error: Cannot find module 'webpack/lib/RequestShortener'

于是手动更新webpack,npm install webpack@latest --save-dev

再运行vue inspect > webpack-config.js ERROR Error: Cannot call .tap() on a plugin that has not yet been defined. Call plugin('preload').use() first. Error: Cannot call .tap() on a plugin that has not yet been defined. Call plugin('preload').use() first.

这个错误通常是由于Webpack插件的使用顺序问题导致的。具体来说,Webpack要求在调用.tap()方法之前,必须先调用.use()方法来定义插件。

需要更改下插件的调用方式

比如原先的:

 
  

ruby

复制代码

config.plugin("preload").tap(() => [     {        rel: "preload",        // to ignore runtime.js        // https://github.com/vuejs/vue-cli/blob/dev/packages/@vue/cli-service/lib/config/app.js#L171        fileBlacklist: [/.map$/, /hot-update.js$/, /runtime..*.js$/],        include: "initial",     },   ]);

改成:

 
  

javascript

复制代码

const PreloadWebpackPlugin = require('preload-webpack-plugin'); config.plugin('preload').use(PreloadWebpackPlugin, [     {        rel: 'preload',        fileBlacklist: [/.map$/, /hot-update.js$/, /runtime..*.js$/],        include: 'initial',     },   ]);

接着依次更改下所使用的插件

随后运行vue inspect > webpack-config.js

报错:

Error: Cannot find module 'preload-webpack-plugin'

查找了些资料发现:

在Webpack 5中,一些插件或工具可能需要额外安装,这可能是因为Webpack 5对插件系统或依赖项有所改变,导致某些插件不再默认包含在Webpack中。这可能是为了减少Webpack的体积,提高灵活性,或者是对插件生态系统的调整。

于是安装npm install preload-webpack-plugin

再次运行vue inspect > webpack-config.js

可以看到根目录下出现了一个webpack.config.js配置文件。

开始运行项目npm run serve

问题1:

发现报错 ERROR TypeError: compiler.plugin is not a function TypeError: compiler.plugin is not a function 发现 preload-webpack-plugin和webpack5不兼容,

暂时先干掉

问题2

发现报错 options has an unknown property 'overlay'. These properties are valid:webpack

在将webpack4升级到webpack5时,webpack-dev-server的配置项发生了一些变化。对于overlay属性,webpack5中已经不再支持这个属性,而是使用了新的方式来处理警告和错误。可以将overlay属性替换为client属性,并设置overlay为true来实现类似的功能。

原来的

 
  

yaml

复制代码

devServer: {    port: port,    open: true,    overlay: {      warnings: false,      errors: true,   },    ...

现在的

 
  

yaml

复制代码

devServer: {    port: port,    open: true,    client: {      overlay: {        warnings: false,        errors: true     }   },

问题3:

继续报错

[@vue/compiler-sfc] the >>> and /deep/ combinators have been deprecated. Use :deep() instead. >>>和/deep/这两个组合选择器已经被弃用,取而代之的是使用:deep()伪类选择器来实现相同的功能。 这个需要更改原先的业务代码,而且改动较大,暂时搁置

问题4:

代码有很多不规范的写法导致编译报错

VueCompilerError: