vue项目中使用插件,如果不做分离处理,打包之后这些插件都会被打包到chunk.vendors.js里,会导致这个js文件很大,为了减少请求阻塞,将一些大插件分离出来,用cdn的方式加载,能够减小自己服务器的压力
较大插件在打包后导致chunk.vendors.js过大
- 首次访问网站的时候,chunk.vendors.js过大会导致请求时间过长,影响体验,而如果不做分离处理,所有插件都会被打包到这里,所以把几个较大的插件分离出来,用cdn的方式加载,提高刚问速度
- 例如可以分离出来的插件有:vue, vue-router, vuex, axios 和 echarts
- 分离的具体步骤:
- 在vue.config.js中声明一个需要分离的插件对象assetsCDN,其中包括分离出来后使用的cdn链接
const assetsCDN = { // 解决chunk.vendors.js打包后文件过大问题,用cdn加载这里的插件
externals: {
'vue': 'Vue',
'vue-router': 'VueRouter',
'vuex': 'Vuex',
'axios': 'axios'
},
css: [
],
js: [
'https://cdn.bootcdn.net/ajax/libs/vue/2.6.14/vue.min.js',
'https://cdn.bootcdn.net/ajax/libs/vue-router/3.5.1/vue-router.min.js',
'https://cdn.bootcdn.net/ajax/libs/vuex/3.1.1/vuex.min.js',
'https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.min.js'
]
}
- 在configureWebpack中配置externals属性,为生产环境时分离,然后配置optimization属性分离module,当一个module的大小大于最小值了,就进行分离,至于分离出来之后是走cdn还是走后台,就时看externals中配置的哪些是走cdn
const vueConfig = {
// 基本路径
publicPath: './',
assetsDir: 'static',
configureWebpack: {
// if prod, add externals
externals: isProd ? assetsCDN.externals : {},
// 开启分离 js
optimization: {
runtimeChunk: 'single',
splitChunks: {
chunks: 'all',
maxInitialRequests: Infinity,
minSize: 20000,
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name (module) {
// get the name. E.g. node_modules/packageName/not/this/part.js
const packageName = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)[1]
// npm package names are URL-safe, but some servers don't like @ symbols
return `npm.${packageName.replace('@', '')}`
}
}
}
}
}
},
chainWebpack: config => {
...//看下面
}
}
- 既然要走cdn了,那就应该引入其script标签才对,所以还需要在webpack配置中,加一个script标签的链接资源,传递给html
chainWebpack: config => {
if (isProd) {
config.plugin('html').tap(args => {
args[0].cdn = assetsCDN
return args
})
}
},
- 最后在index.html中通过这段代码引入webpack传递过来的script标签
<!-- require cdn assets js -->
<% for (var i in htmlWebpackPlugin.options.cdn && htmlWebpackPlugin.options.cdn.js) { %>
<script type="text/javascript" src="<%= htmlWebpackPlugin.options.cdn.js[i] %>"></script>
<% } %>
<!-- built files will be auto injected -->