Vite 原理详解:为什么这么快?

1. 面试题

Q: Vite 为什么比 Webpack 快?它的核心原理是什么?

2. 核心解答

Vite 的快主要体现在 开发环境 (Dev Server) 的冷启动和热更新上。

(1)Bundleless (无打包构建)

Webpack 必须先从入口出发,分析依赖,编译所有模块,打包成 Bundle,才能启动开发服务器。项目越大,启动越慢。 Vite 利用现代浏览器原生支持的 ES Modules (ESM) 特性。

  • 它不需要打包。
  • 当你请求 index.html 时,浏览器发现 <script type="module" src="/src/main.js">,就会向服务器请求 main.js
  • Vite 收到请求后,按需编译这个文件 (转译 TS/JSX),然后返回给浏览器。
  • 浏览器解析到 import 又会发起新的请求。
  • 核心优势按需编译 (On-demand Compilation)。不管项目多大,启动时间几乎恒定。

(2) Esbuild 预构建

Vite 使用 Esbuild (Go 编写,比 JS 快 10-100 倍) 来处理第三方依赖 (node_modules)。

  • CommonJS -> ESM:将非 ESM 的包转换为 ESM,以便浏览器加载。
  • 合并请求:将拥有数百个内部文件的库 (如 lodash) 打包成一个文件,避免浏览器发起数百个 HTTP 请求导致拥塞。
  • 强缓存:依赖一旦构建,就会被强缓存 (Cache-Control: immutable),下次启动秒开。

(3) HMR (热更新) 优化

  • Webpack:修改一个文件,可能导致整个 Bundle 重新构建 (尽管有缓存)。
  • Vite:修改一个文件,Vite 只需要让浏览器重新请求该模块即可。HMR 速度与项目总大小无关,始终是毫秒级。

3. 面试加分项

Q: 生产环境也是 Bundleless 吗?

不是。生产环境使用 Rollup 进行打包。 为什么不用 Esbuild 打包?因为 Esbuild 目前对代码分割 (Code Splitting) 和 CSS 处理的支持还不够成熟,打包产物不如 Rollup 优化得好 (比如 Tree Shaking)。Vite 权衡了开发体验 (Esbuild) 和产物质量 (Rollup)。

4. 总结

  • Dev: Native ESM (No Bundle) + Esbuild (Pre-bundle).
  • HMR: File request based (Instant).
  • Prod: Rollup (Optimized Bundle).