项目中的第三方库默认会被打包到一个文件名含vendors的bundle中,如果你的项目里面引用的第三方库过多,那么你的vendors就会很臃肿,文件也会变大,网站加载该文件的时候就越耗时,从而影响网站性能。这个时候我们可以考虑把一些比较大的第三方库从vendors中分离出来,或者直接配置cdn。这里我们主要来讲如何在cli4中单独打包第三方库文件从而实现bundle分割,减小vendors文件体积的目的。有关cli4 配置cdn可以参考笔者的另外一篇博客 vue cli4 配置资源CDN
下面的配置都在vue.config.js文件中进行,这是cli指定的的配置文件,如果项目没有这个文件,就自己创建一个。接下来我们需要在configureWebpack中配置splitChunks,下面是配置的相关代码:
configureWebpack: config => {
config.optimization = {
splitChunks: {
chunks: 'all',
cacheGroups: {
vue: {
name: 'vue',
test: /[\\/]node_modules[\\/]vue[\\/]/,
priority: -10
},
vuex: {
name: 'vuex',
test: /[\\/]node_modules[\\/]vuex[\\/]/,
priority: -10
},
'vue-router': {
name: 'vue-router',
test: /[\\/]node_modules[\\/]vue-router[\\/]/,
priority: -10
},
'element-ui': {
name: 'element-ui',
test: /[\\/]node_modules[\\/]element-ui[\\/]/,
priority: -10
},
'vendors': {
name: 'vendors',
test: /[\\/]node_modules[\\/]/,
priority: -20
}
}
}
}
}
configureWebpack有对象和函数两种写法,这里选了函数的写法。没什么特别的就是个人习惯而已。chunks: 'all'是指对于所有的块进行优化,他还有另外两个选项initial和async, 这里不做展开。最主要是配置cacheGroups里面的内容,比如我们拿分离element-ui为例:
'element-ui': {
name: 'element-ui',
test: /[\\/]node_modules[\\/]element-ui[\\/]/,
priority: -10
}
其中name是指定打包之后的bundle文件名(如果无name配置,最后的bundle文件名就是外层的element-ui加上入口文件的组合,例如element-ui~index),test则是匹配需要分离的第三方库所在的目录,element-ui所在的目录是在/node_modules/element-ui/,不清楚的朋友可以自己去node_modules文件夹下搜索。priority指定打包的优先级,这个值必须要比vendors的打包优先级大,不然便无法成功分离指定的第三方库,他仍然会被打包到vendors中)下面放送vue.config.js的所有配置内容,如下:
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
module.exports = {
publicPath: '/',
filenameHashing: true,
productionSourceMap: process.env.NODE_ENV !== 'production',
devServer: {
port: 8077
},
chainWebpack: config => {
config.resolve.symlinks(true)
if (process.env.VUE_APP_TYPE === 'analyze') {
config.plugin("webpack-report").use(BundleAnalyzerPlugin, [
{
analyzerMode: "static"
}
])
}
},
configureWebpack: config => {
config.optimization = {
splitChunks: {
chunks: 'all',
cacheGroups: {
vue: {
name: 'vue',
test: /[\\/]node_modules[\\/]vue[\\/]/,
priority: -10
},
vuex: {
name: 'vuex',
test: /[\\/]node_modules[\\/]vuex[\\/]/,
priority: -10
},
'vue-router': {
name: 'vue-router',
test: /[\\/]node_modules[\\/]vue-router[\\/]/,
priority: -10
},
'element-ui': {
name: 'element-ui',
test: /[\\/]node_modules[\\/]element-ui[\\/]/,
priority: -10
},
'vendors': {
name: 'vendors',
test: /[\\/]node_modules[\\/]/,
priority: -20
}
}
}
}
},
pages: {
index: {
entry: 'src/main.ts',
template: 'public/index.html',
filename: 'index.html',
title: 'sass-admin',
chunks: ['vendors', 'vue', 'vuex', 'vue-router', 'element-ui', 'index']
}
}
}
大家重点关注 configureWebpack的配置内容即可,其余部分配置是笔者自己demo的配置。需要注意的是一定不要忘了把分离出来的bundle加入到pages中的chunks里面,这里的chunks指定了入口所需要加载的js文件。
在cacheGroups中配置完需要分离的库后,我们可以进行打包看一下最后的结果。下面是配置前后的打包分析图和本地dist文件下的文件情况。
配置后的打包分析图和dist文件夹下的内容:
可以看到,我们通过配置configureWebpack的splitChunks成功的把element-ui,vue-router,vue,vuex这些第三方库从vendors中分离了出来,达到了我们的目的。
configureWebpack其实是对cli内部的webpack进行配置,打包时cli会通过webpack-merge把configureWebpack的内容与最终的webpack配置进行合并。所有webpack支持的配置都可以在configureWebpack里面配置。splitChunks来源于SplitChunksPlugin这个插件(cli内部有集成,这也符合cli开箱即用的理念),有关splitChunks更多的内容大家可以查看split-chunks-plugin的文档。介绍到此结束,如有疑问可于下方留言。