// vue-config.js
chainWebpack: config => {
// split chunks
config.
when(process.env.NODE_ENV !== 'development', config => {
config
.optimization.splitChunks({ // https://webpack.js.org/plugins/split-chunks-plugin/#splitchunkschunks
chunks: 'all', // Providing all can be particularly powerful, because it means that chunks can be shared even between async and non-async chunks
cacheGroups: {
libs: {
name: 'chunk-libs',
test: /[\\/]node_modules[\\/]/,
priority: 10,
chunks: 'initial' // only package third parties that are initially dependent
},
elementUI: {
name: 'chunk-elementUI', // split elementUI into a single package
priority: 20, // the weight needs to be larger than libs and app or it will be packaged into libs or app
test: /[\\/]node_modules[\\/]_?element-ui(.*)/ // in order to adapt to cnpm
},
commons: {
name: 'chunk-commons',
test: /[\\/]src[\\/]components[\\/]Base[A-Z]\w+\.(vue|js)$/, // only base components
minChunks: 3, // minimum common number
priority: 5,
reuseExistingChunk: true // If the current chunk contains modules already split out from the main bundle, it will be reused instead of a new one being generated. This can impact the resulting file name of the chunk.
},
date: {
name: 'chunk-date',
test: resolve('src/lib'), // date picker lib
priority: 4,
reuseExistingChunk: true
}
}
})
})
}
preload all chunks (vendor, async, normal chunks) using include: 'all',preload all chunks (vendor, async, normal chunks) using include: 'all', or only preload initial chunks with include: 'initial':
In case you work with named chunks, you can explicitly specify which ones to include by passing an array:
另一个解决方案代码:
// @rewrite webpack setting
chainWebpack: config => {
// preload the chunks split by u self
config.plugins('preload')
.tap(options => {
// for import() lazy routes use initial https://github.com/vuejs/preload-webpack-plugin
options.include = 'initial'
// or split chunks at the bottom
// options.include = ['chunk-libs', 'chunk-elementUI', 'chunk-commons', 'chunk-date']
return options
})
// remove the prefetch plugin
config.plugins.delete('prefetch')
}
基本上一天把项目上需要用到的
webpack
手撸了一遍。涉及splitChunks
、preload
、workbox
splitChunks
webpack 相关文档:webpack splitChunks
vue-cli 相关文档: vue-cli
webpack-chain文档: webpack-chain
webpack chunk
它内置的代码分割策略是这样的:新的 chunk 是否被共享或者是来自 node_modules 的模块
新的 chunk 体积在压缩之前是否大于 30kb
按需加载 chunk 的并发请求数量小于等于 5 个
页面初始加载时的并发请求数量小于等于 3 个
我们实际开发中处理
chunk
往往是一些不容易发生变更的文件、引用次数较多:node_modules
、全局公用组件、一些函数等preload or prefetch
@vue/preload-webpack-plugin
preload
是一种 resource hint,用来指定页面加载后很快会被用到的资源,所以在页面加载的过程中,我们希望在浏览器开始主体渲染之前尽早 preload。prefetch
是一种 resource hint,用来告诉浏览器在页面加载完成后,利用空闲时间提前获取用户未来可能会访问的内容。 单页面应用中当页面数量较多是需要async import
和这两个策略是冲突的,一开始尽可能的缓存更多资源,页面需要加载更多请求,非常容易出现首屏时间过长等问题,当然最粗暴的方法就是 删除这两个配置官网上还提供了一个配置项
include
,它可以是一个字符串(all所有、initial初始)or数组(chunk名)另一个解决方案代码:
work box
这个是
service woker
的一个插件,具体用法查看官方文档也可以查阅pwa
相关资料