本文详细介绍 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 两端

Vite 构建原理详解