Vite 开发服务器核心原理讲解
# 🎯 总目标
理解 Vite 开发服务器(Dev Server)内部到底干了什么?为什么快?
核心关注三个问题:
- 启动时发生了什么?
- 浏览器请求文件时 Vite 怎么处理?
- HMR(热更新)工作流程是什么?
最终你会从“使用者” → “实现者”的视角理解 Vite。
# 🧱 1. Vite Dev Server 的核心架构概览
Vite 开发服务器本质上由三大部分组成:
┌──────────────────────────┐
│ Vite │
│ (开发服务器) │
└──────────────────────────┘
│ │ │
▼ ▼ ▼
File Resolver Transforms (Plugin Pipeline)
(路径解析) (插件转换:ts/vue/jsx/css等)
│
▼
Native ESM Server
(用浏览器原生 ES Modules 提供模块)
2
3
4
5
6
7
8
9
10
11
12
13
开发环境最关键的两点:
# ✔ No-Bundle 开发(不打包)
# ✔ HMR Server(超快热更新)
# 🚀 2. Vite 开发服务器启动流程
当你运行:
npm run dev
其核心流程:
# 🔸 Step 1:解析配置
vite.config.ts → 加载插件 → 解析插件 hook → 合并默认配置。
# 🔸 Step 2:构建插件容器(plugin container)
插件容器由 Vite 实现,用来执行 Rollup 风格的插件:
- resolveId()
- load()
- transform()
所有文件都通过这个“插件流水线”处理。
# 🔸 Step 3:启动一个 Connect 中间件服务器
Vite 基于 connect(与 Express 类似)实现中间件服务器:
const server = connect()
然后注册各种中间件:
- 处理静态资源
- 处理 HMR WebSocket
- 处理模块解析
- 处理 transform
- 处理 Vue 编译
- 处理 TS 转 JS
- 处理 CSS / PostCSS
# 🔸 Step 4:启动 WebSocket(用于 HMR)
HMR 通过 WebSocket 推送更新:
ws.send(JSON.stringify({
type: "update",
path: "...",
timestamp: ...
}))
2
3
4
5
浏览器中的 HMR 客户端收到后会执行:
- reload component
- refresh css
- update module graph
# 🔸 Step 5:打印服务器地址
Local: http://localhost:5173/
至此 Vite Dev Server 启动完成。
# 🔥 3. 浏览器访问页面时 Vite 是如何工作的?
当浏览器访问:
/src/main.ts
Vite 并不会从磁盘直接返回这个文件。 它会通过 插件流水线处理,再返回。
流程如下:
# 📌 Step 1:路径解析(resolveId)
例如:
import { createApp } from 'vue'
浏览器会请求:
/node_modules/.vite/deps/vue.js?v=xxxx
Vite 的 resolver 负责:
- 将裸模块名
'vue'变成实际路径 - 对第三方依赖进行“依赖预构建”(优化)
- 缓存解析结果
# 📌 Step 2:transform(插件处理)
每个文件都会经过完整插件链:
source → load() → transform() → transformIndexHtml() → 返回浏览器
例如:
- TS → JS(esbuild)
- Vue → JS(@vitejs/plugin-vue)
- JSX → JS
- CSS → JS 模块
- PostCSS → 转换
- 自动依赖预构建
- Auto import 插件
- 你的自定义 transform 插件
最终所有内容都变成 原生 ESM JS 模块,返回浏览器。
# 📌 Step 3:返回 ESM 响应
返回的 JS 模块是带有 ESM import 的:
import { createApp } from "/node_modules/.vite/deps/vue.js?v=xxxx"
浏览器再次发起新的请求,Vite 再次解析、转换、返回。
这就是为什么 Vite 不需要一次性打包所有模块。
# ⚡ 4. 为什么 Vite 开发服务器极快?
原因 = 没有任何 bundle + ESM 文件按需加载。
# ⭐ 原因 1:浏览器支持 ESM,Vite 只是“路由器”
Vite 不需要提前打包。浏览器解析到 import 才会加载模块。
这意味着:
- 启动时间与项目大小无关
- 冷启动几乎瞬间完成
Webpack 需要:
构建依赖图 → 打包所有模块 → 输出 bundle
# ⭐ 原因 2:使用 esbuild 做依赖预构建(100 倍快)
第三方依赖(Vue、React、Lodash)用 esbuild 预构建成 ESM,速度极快。
让进口模块加载速度大幅提升。
# ⭐ 原因 3:文件只在第一次请求时转换并缓存
Vite 内部有强缓存:
if cache exists → return transformed result
else transform → cache → return
2
# 🔥 5. Vite HMR(热更新)核心机制
这是 Vite 快的真正核心。
流程如下:
# 📌 Step 1:监视文件(fs watcher)
Vite 使用 chokidar 监听文件变化:
chokidar.watch(root)
# 📌 Step 2:更新模块图(Module Graph)
每个文件都会在 ModuleGraph 中记录:
- importers(谁用它)
- imported modules(它用谁)
- 依赖关系
文件变化 → ModuleGraph 更新。
# 📌 Step 3:触发插件的 handleHotUpdate()
每个插件可决定:
- 哪些模块需要 HMR
- 返回更新的部分
例如 Vue 插件:
handleHotUpdate(ctx) {
if (file ends with .vue) {
return [template part, script part]
}
}
2
3
4
5
# 📌 Step 4:Vite 将更新推送给浏览器(WebSocket)
{
"type": "update",
"path": "/src/App.vue",
"timestamp": 1234567
}
2
3
4
5
# 📌 Step 5:浏览器侧执行 HMR
Vite 自带客户端模块:
@vite/client
处理各种类型的 HMR:
- Vue:热更新组件,不刷新页面
- React:react-refresh
- CSS:替换 标签
- JS:替换模块
- Full-reload:整体刷新页面(仅无法精确更新时)
# 🧠 6. Dev Server 核心代码结构(源码视角)
爆裂干货区域 ↓
Vite Dev Server 代码位置:
packages/vite/src/node/server/index.ts
packages/vite/src/node/server/middlewares/
packages/vite/src/node/server/hmr.ts
packages/vite/src/node/server/moduleGraph.ts
2
3
4
最核心的几个模块:
# ✔ createServer()
启动整个开发服务器
# ✔ moduleGraph
管理模块依赖关系
# ✔ pluginContainer
运行 rollup 风格 transform/load/resolve 插件
# ✔ middlewares
按顺序处理请求,如:
- transformMiddleware
- serveStaticMiddleware
- indexHtmlMiddleware
- hmrMiddleware
# 🎉 7. 一张图总结 Vite Dev Server 核心原理
Browser
│
▼ (ESM import)
HTTP Request /src/main.ts
│
▼
┌────────────────────────┐
│ Vite Dev Server │
├────────────────────────┤
│ 1. Resolve (插件) │
│ 2. Load (插件) │
│ 3. Transform (插件链) │
│ 4. Return ESM code │
├────────────────────────┤
│ Cache / ModuleGraph │
└────────────────────────┘
│
▼
Browser executes ESM
│
File change
│
▼
Vite detects change
│
push HMR update
│
▼
Browser reload module
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
你现在已经拥有了 Vite Dev Server 的完整理解。