如何在webpack中拆分来自node_modules的bundle打包文件?
针对bootstrap-vue与vue-tel-input的拆包及体积优化方案
1. 按需引入替代全量引入
这是收益最高的优化手段,可直接降低打包体积60%以上:
- 针对
bootstrap-vue:移除全量注册逻辑,改为仅注册项目实际使用的组件、指令。如果使用Babel,可搭配babel-plugin-bootstrap-vue实现自动按需引入,无需手动逐个导入组件。 - 针对
vue-tel-input:该库默认打包了全球所有国家的手机号区号数据,可根据业务覆盖的地区裁剪冗余数据。仅保留目标地区的区号数据后,该库打包体积可降至原有的30%左右,webpack可通过配置alias替换全量区号文件为自定义精简文件,vite可使用对应按需裁剪插件实现。
2. 细化打包拆包粒度
调整打包工具的拆包规则,进一步拆分冗余依赖:
- 配置webpack的
splitChunks或vite的manualChunks,将两个库依赖的公共第三方包单独拆分为独立chunk,避免重复打包。参考webpack配置示例:
module.exports = { optimization: { splitChunks: { cacheGroups: { // 拆分bootstrap-vue "bootstrap-vue": { test: /[\\/]node_modules[\\/]bootstrap-vue[\\/]/, name: "bootstrap-vue", chunks: "all", priority: 10, enforce: true }, // 拆分vue-tel-input "vue-tel-input": { test: /[\\/]node_modules[\\/]vue-tel-input[\\/]/, name: "vue-tel-input", chunks: "all", priority: 10, enforce: true }, // 拆分两个库共享的底层依赖,避免重复打包 "common-thirdparty": { test: /[\\/]node_modules[\\/](popper\.js|libphonenumber-js)[\\/]/, name: "common-thirdparty", chunks: "all", priority: 20 } } } } }
- 开启Tree Shaking,同时在
package.json的sideEffects字段中声明两个库的样式文件路径,避免有用的样式代码被误剔除。
3. 非首屏依赖懒加载
如果这两个组件不需要在首屏渲染,直接将使用这两个组件的页面/组件配置为异步懒加载:
// Vue组件级懒加载示例 const TelInputModule = () => import('./components/TelInputModule.vue')
配置后两个依赖的chunk只会在用户触发对应功能时加载,不会占用首屏加载时长,可直接提升Lighthouse性能得分。
4. 精简替代方案
如果上述优化后仍不满足体积要求,可替换为更轻量的实现:
- 若仅使用bootstrap-vue的少量组件,可直接引入原生bootstrap并自行封装简易Vue组件,不需要引入整个组件库。
- 若仅需要基础的手机号输入校验能力,可基于
libphonenumber-js自行封装极简输入组件,整体体积可控制在50KiB以内。
内容的提问来源于stack exchange,提问作者Eboua Osée
相关产品推荐
相关产品推荐

