当项目体积增长,所有代码打进一个巨大的 JS 文件会导致首屏加载变慢,且改动一行代码用户就得重新下载整个包。分包(Code Splitting) 就是把产物拆成多个更小的 chunk,让浏览器并行加载,并利用缓存减少重复下载。
Vite 底层打包基于 Rollup,分包策略通过 build.rollupOptions.manualChunks 来定义。一个真实可用的 vite.config.js 配置示例如下:
// vite.config.js
import { defineConfig } from 'vite'
export default defineConfig({
build: {
rollupOptions: {
output: {
manualChunks: {
// 把 Vue 全家桶单独拆成一个 vendor 包 (稳定,易缓存)
'vue-vendor': ['vue', 'vue-router', 'pinia'],
// 把大型 UI 库独立拆出 (如 Element Plus)
'element-plus': ['element-plus'],
// 把通用的工具库归到一起
'common-utils': ['lodash-es', 'axios', 'dayjs'],
}
}
}
}
})
分包的核心原则:
- 稳定性优先:将不常变动的第三方依赖(框架、组件库)抽离为独立 chunk,这些文件长期不变,命中浏览器强缓存,用户后续访问无需重新下载。
- 控制 chunk 大小:单个 chunk 建议不超过 300KB (gzip后约 90KB),过大则拆,过细则增加请求数。
- 避免过细拆分:过度分包导致大量并行请求反而降低加载效率,一般把公共依赖拆成 3-5 个包就足够。
针对动态导入的自动分包:只要在代码中使用 import() 语法(路由懒加载、异步组件),Vite 会自动识别并生成独立 chunk,无需额外配置。对于大型业务模块(如后台管理中的“用户管理”、“订单管理”),推荐直接使用路由懒加载,让这些代码在该功能被访问时才加载。
// router/index.js
const UserList = () => import('@/views/UserList.vue')
真实项目中常见的分包策略:
- 纯净 vendor:
vue、vue-router、pinia等核心库打包为一个 chunk; - UI 组件库:
element-plus、ant-design-vue等单独打包; - 图表库/ECharts:体积巨大且非首屏必需,建议配合动态引入单独拆出;
- 业务公共组件:如果多个页面复用的业务模块占比不小,也可提取公共 chunk(Vite 默认会自动提取多入口共享的模块到公共 chunk)。
配置完成后,运行 npm run build,在 dist 目录中即可看到拆分出的多个 JS 文件。通过 rollup-plugin-visualizer 可视化的体积分析图,可以直观判断分包是否合理。
静态资源处理
Vite 对图片、CSS、字体等静态资源的处理是开箱即用的,但了解其默认行为与配置项能帮助我们根据部署环境灵活调整。
图片与媒体资源
当你在代码中 import 一个图片时:
import logoUrl from '@/assets/logo.png'
// logoUrl 在开发时是 /src/assets/logo.png
// 生产构建后变成 /assets/logo.8d283b.png (带哈希)
构建时图片会经过以下流程:
- 资源哈希:文件名加入内容哈希,便于缓存;
- 自动内联:小于
assetsInlineLimit(默认 4KB)的图片会被转为 base64 内联到 JS/CSS 中,减少 HTTP 请求; - 大于阈值的文件:输出到
dist/assets/目录,保持独立文件引用。
自定义阈值:
build: {
assetsInlineLimit: 1024 * 8 // 8KB 以下才内联
}
对于不希望被内联的大图(如背景图、首页大图),可以直接放在 public 目录下,通过绝对路径引用(如 /banner.jpg)。public 目录中的资源不会被 Vite 处理,构建时直接拷贝到 dist 根目录,适合需要保持特定文件名(如 favicon.ico、robots.txt)或需要在运行时动态替换的静态文件。
CSS 与样式资源
- CSS 提取:生产构建时,所有 CSS 会提取为独立的
.css文件,避免 JS 体积膨胀; - PostCSS 处理:Vite 自动读取项目根目录的
postcss.config.js,可直接集成 Autoprefixer、px-to-viewport 等插件; - Sass/Less:安装相应预处理器后,直接导入
.scss、.less文件即可,无需额外配置; - CSS Modules:以
.module.css结尾的样式文件自动开启模块化,避免类名冲突。
静态资源部署路径(base)
部署到不同路径(如 /app/)或 CDN 时,需要配置 base 选项,它会影响所有静态资源的引用路径:
// 部署到 https://example.com/my-app/ 下
base: '/my-app/'
// 使用 CDN 前缀
base: 'https://cdn.example.com/assets/'
正确配置后,构建产物中所有资源路径都会自动添加该前缀,无需手动修改。开发环境同样适用,代理配置也要相应调整。
资源分类输出
若想让不同类型的资源输出到不同目录,可以使用 build.rollupOptions.output 的 assetFileNames 指定命名规则:
output: {
assetFileNames: (assetInfo) => {
// 图片类资源
if (/\.(png|jpe?g|gif|svg|webp)$/.test(assetInfo.name)) {
return 'images/[name]-[hash][extname]'
}
// CSS 文件
if (/\.(css)$/.test(assetInfo.name)) {
return 'css/[name]-[hash][extname]'
}
// 其他资源(字体等)
return 'assets/[name]-[hash][extname]'
}
}
这样可以保持构建目录结构清晰,方便日志分析与缓存策略管理。
最佳实践:
- 小图标用 SVG Sprite 或内联 base64,减少请求;
- 大图使用
public目录 + CDN 分发; - 始终设置合理的
assetsInlineLimit,避免 JS 体量因内联图片而暴涨; - 部署前用
vite preview本地预览生产构建,确保资源路径无误。
通过对分包和静态资源的恰当配置,Vue 项目的加载性能与部署灵活度能够在不增加开发负担的前提下得到显著提升。