Vite 为什么会成为下一代前端构建工具

0 阅读3分钟

很多观点只停留在“Vite 用 ESM,所以快”,但真正的核心其实是 开发服务器架构 + Module Graph + HMR 机制


一、Vite 的核心架构

Vite 的开发服务器本质是一个 按需编译的 HTTP Server

整体架构可以理解为:

BrowserHTTP RequestVite Dev ServerPlugin PipelineTransform (esbuild / plugins)
   │
Return ESM

关键点:

浏览器驱动编译

也就是说:

浏览器请求什么
Vite 才编译什么

例如:

index.html
  ├── main.ts
       ├── App.vue
       ├── router.ts
       └── store.ts

浏览器请求流程:

GET /main.ts
GET /App.vue
GET /router.ts
GET /store.ts

每个模块都是 独立编译返回


二、Module Graph(Vite 的核心数据结构)

Vite 在内存里维护了一张 模块依赖图

App.vue
  │
  ├── Button.vue
  │       │
  │       └── icon.svg
  │
  └── utils.ts

这个结构叫:

Module Graph

模块节点大概结构:

interface ModuleNode {
  url: string
  importers: Set<ModuleNode>
  importedModules: Set<ModuleNode>
}

作用:

1️⃣ 记录模块依赖关系
2️⃣ 精准 HMR 更新
3️⃣ 快速失效缓存


三、Vite HMR 为什么是毫秒级

在 Webpack 中:

修改文件
   ↓
重新编译 bundle
   ↓
重新计算依赖
   ↓
HMR

但在 Vite:

修改 Button.vue
     ↓
找到 ModuleGraph 节点
     ↓
找到 importers
     ↓
只更新受影响模块

示例:

App.vue
   │
   └── Button.vue

修改 Button.vue:

只更新 Button.vue

不会重新编译整个项目。


四、Vite 的 Transform Pipeline

Vite 的模块处理是一个 插件流水线

request
   │
resolveId
   │
load
   │
transform
   │
return code

例如 .vue 文件:

App.vueVue Plugin
   │
compile SFC
   │
返回 JS module

处理后类似:

import { render } from './App.vue?type=template'
export default {
  render
}

所以浏览器其实加载的是:

JS Module

五、为什么 node_modules 要预构建

浏览器加载 ESM 有一个问题:

lodash-es

可能会产生:

600+ 请求

所以 Vite 用:

esbuild 做 依赖预构建

node_modules
   ↓
esbuild
   ↓
合并成单个 ESM

例如:

lodash
react
react-dom

可能会被打包成:

vendor.js

这样浏览器只请求一次。


六、Vite Dev Server 的缓存系统

Vite 有三层缓存:

1 node_modules 预构建缓存

目录:

node_modules/.vite

内容:

deps
metadata.json

作用:

避免重复 esbuild

2 transform 缓存

每个模块会缓存 transform 结果:

source → transform → cache

如果文件没变:

直接返回缓存

3 HTTP cache

浏览器也会缓存:

ETag
304 Not Modified

减少网络传输。


七、为什么 Webpack 很难做到 Vite 这么快

Webpack 的设计是:

Bundle-first architecture

流程:

Dependency GraphChunk GraphBundle

即:

必须先打包
浏览器才能运行

这意味着:

开发阶段也必须打包

所以即使优化:

HMR
DLL
cache
thread-loader

也很难突破。


八、Vite 是“浏览器驱动构建”

Vite 把构建职责从 构建工具转移到了 浏览器

传统模式:

BundlerBrowser

Vite 模式:

BrowserVite Server

浏览器变成了:

模块加载器

九、为什么说 Vite 是前端工程化的范式升级

前端构建工具其实经历了三代:

第一代:任务流

代表:

  • Grunt
  • Gulp

模式:

task pipeline

第二代:Bundler

代表:

  • Webpack
  • Rollup

模式:

bundle everything

第三代:Native ESM Dev Server

代表:

  • Vite
  • Snowpack

模式:

browser-driven compilation

十、很多人不知道的一个 Vite 细节

Vite 不是完全不打包

在生产环境:

Vite 使用:

Rollup

原因:

浏览器加载:

2000 modules

生产环境会:

chunk splitting
tree shaking
code splitting

最终生成:

assets/
  vendor.js
  main.js

十一、Vite 的未来方向

未来构建工具其实在往 Rust / Go 方向走。

例如:

  • Turbopack
  • Rspack
  • Parcel

趋势:

JS BundlerNative Bundler

因为 JS 写构建工具性能始终有限。


十二、最本质的总结

Vite 快不是因为:

工具优化

而是因为:

架构改变

传统:

源码 → bundle → 浏览器

Vite:

源码 → 浏览器 → 按需编译