Vite 依赖预构建
解释 Vite 开发阶段预构建依赖的原因、缓存位置与 optimizeDeps 常见调整场景。
#concept
#growing
#frontend
#javascript
[!info] related notes
- 所属:开发服务器与 HMR MOC
- 前置:双路径
- 后续:HMR 与模块图
Vite 依赖预构建
这个概念为什么出现
node_modules 里的包常常是:
- CommonJS 或混合导出
- 内部拆成成百上千小文件
- 开发中很少修改
若浏览器对每个深层文件都发 ESM 请求,大量请求与模块瀑布会拖慢页面加载。预构建把依赖转换成 dev 友好的 ESM,并合并请求。
[!abstract] 一句话理解 预构建是开发期对依赖的“缓存型编译”,不等于生产打包或生产拆包策略。
最小可观察示例
场景:接入图表库后首页变慢
// 业务:库存趋势图
import * as echarts from 'echarts'
export function renderStockTrend(el: HTMLElement, points: number[]) {
const chart = echarts.init(el)
chart.setOption({
xAxis: { type: 'category' },
yAxis: { type: 'value' },
series: [{ type: 'line', data: points }],
})
return chart
}
调用方应在容器销毁时调用 chart.dispose(),避免重复初始化遗留实例;容器需有可见尺寸。
建议观察:
pnpm dev
# 首次启动日志中的 dependency pre-bundling / optimizing
ls node_modules/.vite/deps 2>/dev/null | head
期望:
依赖被写到 node_modules/.vite/deps 一类缓存目录;
后续启动可复用缓存;实际收益取决于依赖与文件系统。
结合场景关注点
- 改业务源码通常不必重做全部依赖预构建。
- 增删依赖/改 optimizeDeps 常使缓存失效。
- 预构建修的是 dev 体验,不能代替 prod 分析。
核心规则
- Vite 8 使用 Rolldown;Vite 7 及以前标准实现使用 esbuild
- 配置入口:
optimizeDeps.include/exclude - CJS 依赖通常需要预构建,不应随意
exclude;包含嵌套 CJS 的 ESM 包也要检查其依赖 - 缓存会考虑锁文件、补丁目录状态、相关 Vite 配置与
NODE_ENV;本地手改依赖未触发失效时可用pnpm dev --force,并在浏览器禁用缓存后重新加载 - 先定位导出格式、解析与缓存问题,再决定是否
include,不要靠反复清缓存掩盖问题
常见误区
[!warning] 常见误区:把 optimizeDeps 当成万能拆包配置 Vite 8 生产拆包看
build.rolldownOptions;optimizeDeps 主战场在开发。
本节总结
预构建让“依赖少改、源码常改”的不对称性被正确利用。
自测题
- 为什么预构建主要针对依赖而不是
src?
参考答案
依赖变更频率低、模块数多、格式复杂;源码需要按需即时编译以保持编辑反馈。
延伸阅读
| 资料 | 类型 | 支撑内容 |
|---|---|---|
| Dependency Pre-Bundling | 官方 | 机制与配置 |