前言
Vue-Cli中内置了Webpack,但是配置文件和Webpack也不尽相同。
我们可以通过命令查看对应的Webpack配置。
对于优化主要是两个方面
- 构建速度
- 打包体积
所以不管是分析问题还是解决问题有围绕这连个方面进行处理。
Vue-Cli自带
cache-loader 会默认为
Vue/Babel/TypeScript
编译开启。文件会缓存在node_modules/.cache
中。如果你遇到了编译方面的问题,记得先清缓存目录之后再试试看。
thread-loader 会在多核 CPU 的机器上为
Babel/TypeScript
转译开启。
查看Vue-Cli中的Webpack配置
介绍
Vue-Cli脚手架会有webpack的很多默认行为,因此我们得知道基于Vue-Cli的项目,当前的webpack都配置了啥,然后才能做针对性的分析与优化。
vue-cli-service
暴露了inspect
命令用于审查解析好的 webpack 配置。那个全局的vue
可执行程序同样提供了inspect
命令,这个命令只是简单的把vue-cli-service inspect
代理到了你的项目中。
使用方式:
1 | #根据mode,分别生成开发环境、生产环境的配置 |
输入命令后,在根目录会生产一个webpack.config.production.js
文件
如果vue command not found
的错可以全局安装注册一下vue命令
1 | npm install -g vue-cli |
分析
查看构建时间
说明:https://www.npmjs.com/package/speed-measure-webpack-plugin
安装
1 | npm install --save-dev speed-measure-webpack-plugin |
使用
1 | const SpeedMeasurePlugin = require('speed-measure-webpack-plugin') |
或者
1 | const SpeedMeasurePlugin = require('speed-measure-webpack-plugin'); |
查看构建库大小
VUE CLI内置工具
1 | vue-cli-service build --report |
成功后就会在项目目录下找到/dist/report.html
结果如下图所示:
如果报错
node_modules.bin\vue-cli-service.ps1,因为在此系统上禁止运行脚本。
执行之后就能运行上面的命令了
1 | set-ExecutionPolicy RemoteSigned -Scope CurrentUser |
webpack-bundle-analyzer
Vue CLi就不用这个工具了,但是也可以配置,配置后运行项目打开项目页面的同时也会打开分析页面。
安装
1 | npm install --save-dev webpack-bundle-analyzer |
配置
Webpack配置
1 | const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; |
Vue Cli配置
1 | const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; |
优化
构建速度优化
happypack
安装
1 | npm install --save-dev happypack |
配置
1 | /* |
实测没啥效果
vue-cli-plugin-dll
1 | npm install --save-dev vue-cli-plugin-dll |
接下来就是dll的相关配置,将我们项目中的依赖使用dll插件进行动态链接,这样依赖就不会进行编译,从而极大地提高编译速度,因为这些插件没有编译,在vue.config.js
中进行配置,也很简单
1 | const path = require("path"); |
多入口
1 | const path = require('path') |
配置好之后然后运行,进行你上面配置插件动态链接库的编译
1 | npx vue-cli-service dll |
dll编译完成后会在上面配置的目录下生成dll文件夹,就可以开始跑项目了,因为这些插件都不需要编译,跑起来很流畅,修改后的热更新速度更是显著提升。我以前修改一行代码热更新编译在30秒以上,使用这个以后基本十秒以内搞定。
1 | npm run serve |
多线程优化
Vue-Cli
Vue-Cli已经内置,开启
1 | module.exports = { |
parallel
Type:
boolean
Default:
require('os').cpus().length > 1
是否为 Babel 或 TypeScript 使用
thread-loader
。该选项在系统的 CPU 有多于一个内核时自动启用,仅作用于生产构建。
Webpack
1 | npm install --save-dev thread-loader |
配置
1 | const path = require("path"); |
缓存构建
Webpack 中几种缓存方式:
cache-loader
hard-source-webpack-plugin
以上这些缓存方式都有首次启动时的开销,即它们会让 “冷启动” 时间会更长,但是二次启动能够节省很多时间.
而 Vue-Cli 已经内置了 cache-loader
进行以下两个的缓存了
- babel-loader 的 cacheDirectory 标志
- vue-loader 的 cacheDirectory 标志
所以
Vue Cli没有必要添加
HardSourceWebpackPlugin
HardSourceWebpackPlugin
注意
HardSourceWebpackPlugin 和 speed-measure-webpack-plugin 不能一起使用
详细说明
https://www.npmjs.com/package/hard-source-webpack-plugin
在启动项目时会针对项目生成缓存,若是项目无package或其他变化,下次就不用花费时间重新构建,直接复用缓存。
安装
1 | npm install --save-dev hard-source-webpack-plugin |
配置vue.config.js
为模块提供中间缓存,缓存路径是:node_modules/.cache/hard-source
1 | const HardSourceWebpackPlugin = require('hard-source-webpack-plugin') |
或者
1 | const HardSourceWebpackPlugin = require('hard-source-webpack-plugin') |
更多配置
1 | // 缓存 加速二次构建速度 |
缩小文件检索解析范围
为避免无用的检索与递归遍历,可以使用alias指定引用时候的模块,noParse,对不依赖本地代码的第三方依赖不进行解析。
Vue-Cli默认已进行了如下配置
1 | noParse: /^(vue|vue-router|vuex|vuex-router-sync)$/ |
配置
1 | // 定义getAliasPath方法,把相对路径转换成绝对路径 |
或者
1 | // vue.config.js |
import优化
运用这个插件能在代码使用了import语法的情况下,大大提高代码的编译速度。
安装 babel-plugin-dynamic-import-node
1 | npm install --save-dev babel-plugin-dynamic-import-node |
vue-cli3
修改babel.config.js文件
1 | module.exports = { |
vue.cli2
.babelrc文件
1 | "env": { |
打包体积优化
不生成SourceMap
production环境不生成SourceMap
1 | module.exports = { |
图片压缩
image-webpack-plugin
对图片像素要求没很极致的,这个压缩还是可以使用的,压缩率肉眼看起来感觉是没太大区别。 这里注意一下,我没有对svg进行压缩,原因是压缩的svg,再通过构建时被打包成base64时,生成的base64会有问题,无法访问。
1 | module.exports = { |
gzip压缩
使用 gzip 压缩代码,效果显著。
安装
1 | npm install compression-webpack-plugin |
配置
1 | const CompressionWebpackPlugin = require('compression-webpack-plugin') |
配置CDN
老实说,我不用这个功能的,线上使用 cdn 总让我有一种不安全感,除非公司有自己的 cdn 库,不过这确实也是一种优化方案,效果也还不错。它的配置也很简单,在 externals 中配置,例子:
1 | module.exports = { |
然后在 public/index.html
模板文件中引入 cdn 地址:
1 |
|
我这里使用的是 bootcdn 的地址,需要注意版本问题。
也可以借助 HtmlWebpackPlugin 插件来方便插入 cdn 的引入。
使用 cdn 引入的方式虽然能极大改善网页加载速度,但我还是不会用这个功能,项目还不需要非得这样的优化,也怕 cdn 不稳定。
当然
也可以不用CDN,直接把JS复制到项目下,用相对路径引用即可。
借助 HtmlWebpackPlugin 插件来方便插入 cdn 的引入
1 | //生产环境标记 |
index.html中添加
1 | <% for (var i in htmlWebpackPlugin.options.cdn&&htmlWebpackPlugin.options.cdn.js) { %> |
Vue Cli配置说明
https://cli.vuejs.org/zh/guide/webpack.html
简单的配置方式
调整 webpack 配置最简单的方式就是在 vue.config.js
中的 configureWebpack
选项提供一个对象:
1 | // vue.config.js |
该对象将会被 webpack-merge 合并入最终的 webpack 配置。
链式操作 (高级)
Vue CLI 内部的 webpack 配置是通过 webpack-chain 维护的。这个库提供了一个 webpack 原始配置的上层抽象,使其可以定义具名的 loader 规则和具名插件,并有机会在后期进入这些规则并对它们的选项进行修改。
它允许我们更细粒度的控制其内部配置。接下来有一些常见的在 vue.config.js
中的 chainWebpack
修改的例子。
提示
当你打算链式访问特定的 loader 时,vue inspect 会非常有帮助。
修改 Loader 选项
1 | // vue.config.js |
提示
对于 CSS 相关 loader 来说,我们推荐使用 css.loaderOptions 而不是直接链式指定 loader。这是因为每种 CSS 文件类型都有多个规则,而 css.loaderOptions
可以确保你通过一个地方影响所有的规则。
externals详解
externals 配置提供了不从 bundle 中引用依赖的方式。
简单理解就是不通过npm下载的类库,在html文件中以script引入,然后在页面中使用import导入的这种方式
1 | module.exports = { |
如上配置 我们暴漏了html2canvas
变量,那么代码中的
1 | import html2canvas from "html2canvas"; |
依旧能正常运行,如果不配置这个我们代码中就只能这样写了
1 | const html2canvas = window.html2canvas; |
也就是说我们如上配置就可以
- 完全不变动之前代码中的引用。
- 不建议删除npm引用的包,在
npm install
的时候可能会安装其他版本的包。
升级Vue-Cli
其实上面的优化效果都不明显,升级Vue-Cli的效果是最好的。
查看Vue-Cli版本
1 | vue -V |
升级电脑的Vue-Cli版本
1 | npm uninstall vue-cli -g |
因为vue-cli 5
已经使用上webpack5
,之前vue.config.js
文件的一些webpack
的配置是有一些调整的。
升级项目中的Vue-Cli版本
1 | npm ls core-js |
package.json
1 | { |
注意
devDependencies
中的都替换就行。
vue-template-compiler
要和vue的版本一致。
core-js
要用3.x版本。要添加
uuid
,新版本的vue-cli中默认是没有的。
vue.config.js
1 | const { defineConfig } = require("@vue/cli-service"); |
babel.config.js
该文件无变动。
1 | module.exports = { |
.eslintrc.js
1 | module.exports = { |
jsconfig.json
1 | { |