Chapter 01

认识 Vite 与原理

搞懂 Vite 为什么快——从 bundler 时代的痛点讲起,一步步拆解"原生 ESM 开发 + Rollup 生产打包"的双引擎设计。

1.1 Vite 是什么

Vite(法语"快"的意思,发音 /vit/)是 Evan You(Vue.js 作者)在 2020 年发布的前端构建工具。它同时扮演两个角色:

开发服务器(Dev Server)
启动极快的 HTTP 服务,浏览器请求哪个模块就现场编译哪个,支持 HMR。对应命令:vitevite dev
生产构建工具(Build Tool)
用 Rollup(或 6.x 起的 Rolldown)把源码打包成优化后的静态资源。对应命令:vite build

它不是框架,而是底层构建工具——React、Vue、Svelte、Solid 这些 UI 框架都可以用 Vite 做构建。

1.2 bundler 时代的痛点

webpack、Parcel、Rollup 这类传统 bundler 的工作方式:

  1. 读入口文件,沿 import 遍历整个依赖图
  2. 把所有模块用 babel 等工具编译成浏览器能跑的代码
  3. 合并(bundle)成少量大文件
  4. 服务器把打好的 bundle 返回给浏览器

问题:启动前必须先遍历+编译整个项目。中大型项目有几千到几万个模块,这一步就要 10-60 秒。

// webpack dev server 启动过程
[  0ms] 读配置
[200ms] 构建依赖图
[ 5s]  babel 转译 node_modules
[10s]  babel 转译 src
[12s]  tree-shake + bundle
[15s]  ✅ http://localhost:3000 可访问
// 改一行代码 → 重复第 3-5 步 → 2-5 秒才能看到效果

1.3 Vite 的核心洞察:原生 ESM

从 2019 年起,所有现代浏览器都原生支持 ES Modules

<!-- index.html -->
<script type="module" src="/src/main.ts"></script>

// src/main.ts
import { createApp } from 'vue';
import App from './App.vue';
createApp(App).mount('#app');

浏览器遇到 import 会自己发 HTTP 请求去取那个模块——这意味着 打包不再是必须的。Vite 抓住这点,改成"浏览器按需请求,服务器按需编译":

// Vite dev server 启动过程
[  0ms] 读配置
[100ms] esbuild 预构建 node_modules
[300ms] ✅ http://localhost:5173 可访问

// 浏览器加载页面时
GET /src/main.ts                  → Vite 现场把 .ts 编译成 .js
GET /src/App.vue                  → Vite 把 .vue 拆成 render + style
GET /node_modules/.vite/deps/vue  → 返回预构建好的 esm 版本
ES Modules(ESM)是什么?

ECMAScript 2015 引入的官方 JS 模块系统:import/export 语法。它和 CommonJS(Node 早期的 require/module.exports)、AMD(浏览器早期的 RequireJS)相对。ESM 是静态的(编译期可分析依赖)、异步的、浏览器和 Node 都原生支持。

1.4 双引擎:esbuild + Rollup

Vite 不是一个"新写"的打包器,而是把两个已有的优秀工具组合在一起:

引擎用于语言为什么选它
esbuild开发时预构建依赖、单文件转译(TS/JSX)Go比 Babel 快 10-100 倍,无需配置
Rollup生产构建(vite buildJavaScriptTree-shaking 最成熟,插件生态最丰富
Rolldown(Vite 6+ 可选)未来替代 RollupRustRust 重写的 Rollup,速度数十倍
为什么 dev 用 esbuild,build 用 Rollup?

esbuild 极快,但 Tree-shaking 和 code-splitting 不如 Rollup 成熟;Rollup 输出代码质量最好,但纯 JS 写的,速度中等。Vite 取各家所长:dev 追求速度用 esbuild,build 追求体积用 Rollup。Rolldown 成熟后会统一到一个 Rust 引擎。

1.5 依赖预构建(pre-bundling)

node_modules 里的包很多仍是 CommonJS 格式或有数百个子文件(如 lodash-es),浏览器原生 ESM 处理不了 CommonJS、也会因为几百个小请求慢下来。Vite 的做法:

# 第一次启动时
$ vite
✔ optimizeDeps: scanning imports (12ms)
✔ optimizeDeps: bundling deps with esbuild (180ms)
✔ pre-bundled 23 dependencies → node_modules/.vite/deps/

# 生成的文件
node_modules/.vite/deps/
├── vue.js           # CommonJS/多文件包合并为单 ESM
├── vue-router.js
├── lodash-es.js
└── _metadata.json   # 依赖 hash,变了才重新 bundle

效果:每个依赖只需一次 HTTP 请求,并且全是浏览器友好的 ESM。

1.6 HMR(热模块替换)

传统 webpack HMR 需要遍历依赖图判断该替换哪些模块;Vite 的 HMR 天生精确——文件保存后,Vite 通过 WebSocket 告诉浏览器 "/src/App.vue 变了",浏览器的 import.meta.hot 接受这个消息并只重载该模块。

规模效应:项目不管多大,改一个文件只影响一个模块的更新时间。

1.7 与 webpack 的对比

维度webpackVite
冷启动10-60 秒0.3-2 秒
HMR 延迟0.5-3 秒< 50ms
配置复杂(loader/plugin/resolve...)开箱即用,零配置可跑
TypeScript需 ts-loader / babel-loader原生支持(esbuild)
生产打包自家 bundlerRollup(业界最佳)
生态庞大但老旧复用 Rollup 插件 + 新生态

1.8 Vite 能/不能做什么

能做

不做

1.9 版本与生态

截至 2026 年,主流版本是 Vite 6——引入 Environment API(统一 client/SSR/edge 多环境构建)与可选 Rolldown 引擎。Vite 7 即将 GA,默认启用 Rolldown。

核心生态一览

Vitest(测试)、Vite Plugin 生态(@vitejs/plugin-vue、@vitejs/plugin-react 等)、Nuxt 3/SvelteKit/Astro/Remix(上层框架都用 Vite)、Storybook 7+(切到 Vite)。

1.10 小结与下一步

下一章我们动手:用 npm create vite 脚手架起一个项目,看看它到底长什么样。