在现在前端工程化日趋成熟的背景下,为了更好的利用浏览器http缓存,仅使用构建工具的默认分包策略远远是不够的,这就需要我们进行手动分包,具体如何分包这是值得我们去仔细琢磨的。
构建工具会根据分包配置进行打包输出,并根据文件内容生成 文件指纹 ,而文件指纹则是浏览器缓存的关键,因此我们尽量将很少改动的依赖库、工具方法、代码文件进行独立分包。
分包作用:
- 保持分包文件的指纹稳定,充分利用缓存;
- 减少重复代码;
- 异步加载,import(),动态导入会自动进行分包。
分包策略
- 业务模块独立分包;
- 将小而轻量的稳定包分一个包,eg: lodashjs、momentjs、vueRouter等;
- 将几乎不会变动的资源部署到cdn;
- 将可能会变动的进行独立分包,eg:elementUI、antD等,因为涉及到动态导入,可能开发功能时,会引入新的组件
webpack
默认的分包策略
- 根据入口文件分包
- node_modules单独分包
- 动态导入import()的单独分包
手动分包
js
module.exports = {
configureWebpack: {
// 代码分割配置
optimization: {
splitChunks: {
chunks: 'all', // 对所有模块进行分割
minSize: 20000, // 生成 chunk 的最小体积(字节)
maxSize: 250000, // 限制单个 chunk 最大体积为 250KB
minChunks: 1, // 被引用次数
maxAsyncRequests: 30, // 按需加载时的最大并行请求数
maxInitialRequests: 30, // 入口点的最大并行请求数
automaticNameDelimiter: '~', // 自动命名分隔符
enforceSizeThreshold: 50000, // 强制执行拆分的体积阈值
// 缓存组配置
cacheGroups: {
// 第三方模块
vendors: {
name: 'chunk-vendors',
test: /[\\/]node_modules[\\/]/,
priority: -10, // 优先级
chunks: 'initial'
},
// Element UI 单独分包
elementUI: {
name: 'chunk-elementui',
test: /[\\/]node_modules[\\/]element-ui[\\/]/,
priority: 20, // 优先级高于 vendors
chunks: 'all'
},
// ECharts 单独分包
echarts: {
name: 'chunk-echarts',
test: /[\\/]node_modules[\\/]echarts[\\/]/,
priority: 15,
chunks: 'all'
},
// 公共模块
common: {
name: 'chunk-common',
minChunks: 2, // 最小被引用次数
priority: -20,
chunks: 'initial',
reuseExistingChunk: true // 是否复用已存在的 chunk
}
}
},
// 代码压缩配置
minimizer: [
new TerserPlugin({
test: /\.js(\?.*)?$/i, // 匹配 js 文件
parallel: true, // 启用多进程并行运行
terserOptions: {
compress: {
warnings: false, // 不显示警告
drop_console: process.env.NODE_ENV === 'production', // 生产环境移除 console
drop_debugger: process.env.NODE_ENV === 'production', // 生产环境移除 debugger
pure_funcs: process.env.NODE_ENV === 'production' ? ['console.log'] : [] // 生产环境移除 console.log
},
format: {
comments: false // 移除注释
}
},
extractComments: false // 不提取注释
})
]
},
}
}
vite
默认的分包策略
- 入口文件及其直接依赖会打包到主 bundle
- 异步组件会自动分割成独立的 chunk
- 共享依赖会自动提取到 vendor chunk
- CSS 会在生产环境下被提取到独立文件
手动分包
vite的生产环境是采用rollup进行编译打包的,我们同样需要借助rollup的相关配置进行分包配置。
js
export default defineConfig({
plugins: [vue()],
build: {
rollupOptions: {
// 方式一:配置
// 将 vue 、lodash合并打包到一个venderr文件内
vender: ['vue', 'lodash'], // ['name']: ['moduleA', 'moduleB'],
// 方式二:函数式 运行时机:每运行一个模块都会执行,会把模块的id(路径)回传给我们
// return '包的名称'
manulChunks(id) {
if (
id.includes('node_modules') &&
(id.endsWidth('.js') || id.endsWith('.ts'))
) {
return 'vender';
}
}
}
}
})
此外建议过大的资源使用cdn进行加速