Vue项目build打包webpack优化
- webpack-bundle-analyzer
- 路由懒加载
- 去除map文件
- 给chunk命名
- lodash按需加载
- 优化elementUI
- 优化echarts
- CDN加载
- 文件说明
- app.js
- chunk-vendors.js
webpack-bundle-analyzer
打包分析工具
1、首先安装模块
npm i webpack-bundle-analyzer -D
2、在Vue-Cli3
中配置
// vue.config.js
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
module.exports = {
chainWebpack: config => {
if (process.env.NODE_ENV === 'production') {
config
.plugin('webpack-bundle-analyzer')
.use(BundleAnalyzerPlugin)
}
...
}
3、执行以下命令即可查看
npm run build
查看效果
查看地址为http://127.0.0.1:8888/注:因为在vue.config.js
中限制了process.env.NODE_ENV === 'production'
环境,所以只有在npm run build
打包的时候才会执行,否则默认是都执行,也就是npm run serve
运行的时候也会执行,显然这不是我们想要的结果。
在打包好的线上项目中看我们的文件大小跟这里的数据基本一致
生成的dist/js
目录下的文件
最终打包生成的js/chunk-vendor.js
大小为2.09M。
路由懒加载
之前在router.js
文件中,采用的静态引入的方式
import assetList from './pages/asset-manage/asset-list'
{
path: 'xxx/asset-list',
name: 'asset-list',
component: assetList
}
改为懒加载模式
{
path: 'xxx/asset-list',
name: 'asset-list',
component: () => import('./pages/asset-manage/asset-list')
}
以函数的形式动态引入,这样就可以把各自的路由文件分别打包,只有在解析给定的路由时才会下载路由组件
文件中看到生成了很多的代码chunk
文件,这样就能做到在跳转到指定路由时才加载对应的文件,而不是都集中在一个大的文件中,首屏加载的时候就需要下载这个大文件。
此时,生成的js/chunk-vendor.js
大小为1.58M
去除map文件
文件中我们看到很多map
文件,因为项目打包后,代码都是经过压缩加密的,如果运行报错输出的错误信息无法准确得知是哪里的代码报错,这个文件就可以让我们查到具体报错的位置。
为了保证我们打包后的代码不暴露源码,就需要我们将map
文件隐藏掉,如何做呢?
// vue.config.js
module.exports = {
productionSourceMap: process.env.NODE_ENV === 'production' ? false : true
}
给chunk命名
chunkFileName
是不能灵活自定义,这当然不能忍了,于是便有了魔术注释法!
上面看到打包生成的文件都是chunk-hash.js
的格式,如果想要自定义chunk
文件怎么处理呢?
还记得这么多chunk
是怎么出来的么?对,之前我们把路由文件进行了修改,修改成按需加载,下面进一步修改
// router.js
{
path: '/assetManage/assetList',
name: 'asset-list',
meta: {
breadCrumb: ['资产管理', '资产列表'],
navCode: 'asset-list'
},
component: () => import(/* webpackChunkName: 'asset' */ './pages/asset-manage/asset-list')
}
// vue.config.js
module.exports = {
configureWebpack: {
output: {
chunkFilename: 'js/[name].[chunkhash].chunk.js'
}
}
}
这样打包生成的文件
其他的文件如果也想命名都可以使用这种方法。相同name的会合并成一个文件。
lodash按需加载
import {pick} from 'lodash'
import _ from 'lodash'
// 都改成按需引入
import pick from 'lodash/pick'
优化elementUI
完成上面工作后可以很明显的看到elementUI
占了很大的部分
之前我们引入elementUI
// main.js
import elementUI from 'element-ui'
Vue.use(elementUI)
现在我们改成
// main.js
import { Dropdown,
DropdownMenu,
...
Table } from 'element-ui'
Vue.use(Dropdown)
Vue.use(DropdownMenu)
...
Vue.use(Table)
优化echarts
采用按需加载
之前引入
// main.js
import echarts from 'echarts'
Vue.prototype.$echarts = echarts
现在我们改成按需加载
// 使用到的文件bar.vue
import echarts from 'echarts/lib/echarts'
require('echarts/lib/chart/bar')
require('echarts/lib/component/tooltip')
require('echarts/lib/component/title')
CDN加载
在Vue项目中,引入到工程中的所有js、css文件编译时会打包进vendor
文件中,浏览器在加载该文件之后才能开始显示首屏,若是引入的库众多,那么vendor.js
就会过大,影响首屏体验。
CDN加载就是将工程中引用的外部js、css文件剥离开,不编译到vendor.js
中,而是用资源的形式引用,这样浏览器可以使用多个线程加载外部的库文件。
下面是使用普通加载方式得到的打包后文件的分布
// main.js
import echarts from 'echarts'
Vue.prototype.$echarts = echarts
// 使用的.vue文件
this.echartsObj = this.$echarts.init(document.getElementById(this.id))
下面我们将echarts
使用外部资源引入的方式看看优化后的效果
// vue.config.js
module.exports = {
configureWebpack: {
externals: {
echarts: 'echarts'
}
}
}
// index.html
<!-- 引入外部echarts资源 -->
<script src="https://cdn.bootcss.com/echarts/4.1.0/echarts.min.js"></script>
// main.js
// 将这里引入的echarts注释
// import echarts from 'echarts'
// Vue.prototype.$echarts = echarts
// 使用的.vue文件
this.echartsObj = echarts.init(document.getElementById(this.id))
打包后
从1.6M–>825.99KB
Nice!
CDN加载资源方式的原理是:通过 import echarts from 'echarts'
这种导入方式拿到的变量 echarts
,CDN加载(通过插入 script
标签引入资源的方式)后会将变量挂载到全局 window
中,这样就可以在项目中通过 window.echarts
直接使用,或简写为 echarts
。
所以,如果你的项目中某个资源通过 CDN 加载的方式插入后,在控制台中通过 window.xxx
的方式拿不到变量,说明你的资源有问题。
如果工程很大,首屏时间很长的话可以使用CDN加载Vue
、Vuex
、Vue-Router
等,提升首屏体验。
在vue-cli + element-ui 项目中,如果通过 CDN 方式加载 vue:
- 项目中仍然需要
npm i vue
安装 Vue,否则需要手动配置 VueLoaderPlugin 去解析 .vue 文件。- element-ui 的全局变量是 ELEMENT
- 多语言中 element-ui 的多语言挂载在 ELEMENT.lang.xxx
文件说明
app.js
对于chunk
文件我们知道就是我们懒加载时不同路由文件的内容,那么还有一个app.js
文件,这个文件是打包的各项依赖的集合,比如我们在项目入口文件main.js
文件中引入了vue
、vue-router
、axios
等依赖,具体内容可以通过上面的webpack-bundle-analyzer
分析工具查看。
chunk-vendors.js
这里也是引入的组件,只是把一些大组件代码拆分到了这里。具体内容也可以通过webpack-bundle-analyzer
工具分析查看,我们看到我们的element-ui
就在这里。