本文详细介绍 Vite 的构建原理,并配合流程图展示插件钩子在其中的作用。
1. Vite 的双引擎架构
- 开发阶段 (dev server)
- 使用 esbuild 做依赖预构建(pre-bundle)
- 使用 原生 ESM 按需加载模块
- 插件体系(resolve → load → transform)参与源码处理
- 提供快速的 HMR(热更新)
- 构建阶段 (build)
- 使用 Rollup 做生产构建
- 完全兼容 Rollup 插件体系
- 支持 Tree-shaking / 代码分割 / 产物优化
- 使用 esbuild 做快速压缩(可选 terser)
2. 构建流程图

3. 构建阶段关键步骤
(1)初始化配置
- 解析 vite.config.ts
- 执行插件 config / configResolved
- 根据 mode / command 决定走 serve 或 build 流程
(2)依赖预构建 optimizeDeps
- 用 esbuild 扫描入口依赖
- 转换 CommonJS → ESM
- 将依赖合并到 node_modules/.vite/deps/
(3)Rollup 构建流程
- 入口模块解析,构建依赖图
- 调用插件:resolveId → load → transform
- Tree-shaking:移除未使用代码
- 代码分割:根据动态 import 拆分 chunk
- 输出阶段:generateBundle、writeBundle
(4)产物优化
- CSS 抽取:自动合并、压缩
- 资源内联:小文件转 base64 或内联
- 压缩:默认 esbuild,选项 minify: 'terser'
- 多格式产物:支持 build.lib 输出 ESM/UMD/CJS
4. 插件在构建中的作用
Vite 插件在 build 阶段即 Rollup 插件:
- resolveId:控制模块解析(别名/虚拟模块)
- load:提供虚拟模块内容
- transform:源码转换(TS/JSX/MDX/…)
- generateBundle:修改/新增产物
- closeBundle:构建收尾
示例:
export default function MyBuildPlugin() {
return {
name: 'my-build-plugin',
apply: 'build',
buildStart() {
console.log('构建开始')
},
generateBundle(_, bundle) {
console.log('产物清单', Object.keys(bundle))
},
closeBundle() {
console.log('构建完成')
}
}
}5. Vite 优化机制
- 依赖预构建:减少 HTTP 请求数,统一依赖格式
- 智能代码分割:Rollup dynamic import 分包 + manualChunks
- esbuild 加速:预构建与压缩极快
- SSR/Lib 模式支持:灵活输出产物格式
6. 与 Webpack 对比
|
对比点 |
Vite |
Webpack |
|---|---|---|
|
开发模式 |
原生 ESM,HTTP 按需加载 |
先整体打包再启动 |
|
冷启动 |
快(esbuild 预构建 + 按需加载) |
慢(必须完整构建依赖图) |
|
HMR |
基于 ESM 模块级别 |
基于 bundle diff |
|
插件机制 |
Rollup 插件 + Vite 扩展钩子 |
Tapable hooks |
|
打包引擎 |
Rollup |
自研 |
|
压缩 |
esbuild / terser |
terser |
7. 总结
Vite 的构建原理可以归纳为:
开发快靠 esbuild + ESM,构建稳靠 Rollup,插件体系贯穿始终。
- 开发阶段:依赖 esbuild 预构建,按需转译,浏览器原生执行
- 构建阶段:交给 Rollup 做 Tree-shaking、分包、优化
- 插件体系:统一扩展点,支持 dev & build 两端