一、命令行里输入 vite,第一步发生了什么?
1️⃣ Shell 在找:vite 是谁?
你在终端里敲:
bash
vite
Shell(zsh / bash)会按顺序找:
- 是不是内置命令
- 是不是 PATH 里的可执行文件
而 vite 通常来自这里:
bash
node_modules/.bin/vite
为什么能直接敲 vite?
二、node_modules/.bin/vite 是怎么来的?
当你安装 Vite:
bash
npm install vite
npm 做了两件关键的事:
1️⃣ 在 node_modules/vite/ 里装源码
2️⃣ 在 node_modules/.bin/ 里生成一个「软链接 / 启动器」
这个链接来自 vite 的 package.json:
json
{
"bin": {
"vite": "bin/vite.js"
}
}
👉 含义:
当你运行 vite 时,实际上运行的是:
bash
node node_modules/vite/bin/vite.js
三、bin/vite.js 是个什么东西?
你可以理解为:Vite 的入口文件
大致结构是这样的(简化):
js
#!/usr/bin/env node
import { createServer, build } from '../dist/node/index.js'
import { resolveConfig } from '../dist/node/config.js'
// 解析命令行参数
const command = process.argv[2]
if (command === 'build') {
build()
} else {
createServer()
}
这一步做了 3 件事:
-
解析 CLI 参数
vitevite devvite buildvite preview
-
加载 Vite 的核心模块
-
根据命令进入不同流程
四、为什么 vite 默认是 dev,不是 build?
bash
vite
等价于:
bash
vite dev
👉 所以默认走的是:
ts
createServer()
五、createServer() 内部发生了什么?(重点)
这是 Vite 和 Webpack 最大的分水岭。
1️⃣ 读取并合并配置
ts
vite.config.ts
合并顺序:
内置默认配置
→ 插件注入配置
→ 用户配置
→ 命令行参数
2️⃣ 启动一个 HTTP Server(不是打包!)
text
localhost:5173
⚠️ 关键点:Vite dev 模式不打包
3️⃣ 注册一堆中间件(核心)
类似:
ts
server.use(transformMiddleware)
server.use(staticMiddleware)
server.use(hmrMiddleware)
职责分别是:
| 中间件 | 作用 |
|---|---|
| static | 提供静态文件 |
| transform | 按需编译模块 |
| hmr | 热更新 |
| plugin | 插件钩子 |
六、浏览器访问页面时,Vite 才开始"构建"
举个真实流程
浏览器请求:
html
<script type="module" src="/src/main.ts"></script>
Vite 做什么?
-
拦截请求
/src/main.ts -
调用插件链:
tsresolveId → load → transform -
把 TS / Vue / JSX:
ts→ 转成浏览器能执行的 ES Module -
返回结果给浏览器
👉 每个模块是"按需编译"的
七、那 vite build 又是另一条路
bash
vite build
执行路径:
text
vite
→ bin/vite.js
→ build()
→ 调用 Rollup
build 阶段关键点:
| 项 | Vite |
|---|---|
| 实际打包 | Rollup |
| 配置 | 自动转成 Rollup config |
| 插件 | Vite 插件 → Rollup 插件 |
| 输出 | dist/ |
⚠️ Vite 本身不是打包器,它是 dev server + Rollup 封装
八、为什么 Vite 启动这么快?
核心原因只有一句话:
dev 模式下:不打包 + 原生 ES Module
对比:
| 工具 | 启动时做的事 |
|---|---|
| Webpack | 构建整个依赖图 |
| Vite | 启 HTTP 服务,模块按需编译 |
九、一句话总结整个 vite 命令生命周期
text
vite
↓
Shell 找到 node_modules/.bin/vite
↓
Node 执行 bin/vite.js
↓
解析 CLI 参数
↓
createServer()
↓
启动 HTTP Server
↓
浏览器请求模块
↓
Vite 按需编译并返回
十、如果你愿意,下一步可以继续深入 👇
你这个问题已经在构建工具原理线上了,我可以继续带你拆:
- 🔥 Vite 插件机制是怎么设计的?
- 🔥
resolveId / load / transform全流程 - 🔥 HMR 为什么能做到"精准更新"
- 🔥 Vite vs Webpack 在"依赖图构建"上的根本差异
- 🔥 Vite 如何处理 CSS / 资源文件 / 预构建依赖(optimizeDeps)
你挑一个,我按源码级 + 面试级给你讲。