Vite 基础
概述
Vite(法语意为"快")是一个基于原生 ESM 的现代前端构建工具。由 Evan You(尤雨溪)创建,当前已成为前端构建工具的默认首选。
核心特点:
- 开发服务器基于原生 ES Module,无需打包,秒级冷启动
- HMR(热更新)速度极快,与项目大小无关
- 开箱即用支持 TypeScript、JSX、CSS 预处理器等
- 生产构建使用 Rollup(Vite 1-7)/ Rolldown(Vite 8+),确保最优打包
官网: vite.dev
核心原理
1. 原生 ESM(ES Module)
Vite 最大的创新是开发阶段不打包,直接利用浏览器原生 ESM 能力。
工作流程:
浏览器请求 /src/main.ts
↓
Vite 服务器拦截请求
↓
按需编译(TS → JS / SFC → JS)
↓
返回 ESM 模块给浏览器
↓
浏览器自身处理依赖解析浏览器请求 /src/main.ts
↓
Vite 服务器拦截请求
↓
按需编译(TS → JS / SFC → JS)
↓
返回 ESM 模块给浏览器
↓
浏览器自身处理依赖解析- 启动时不做任何模块处理,只有浏览器请求时才编译对应文件
- 启动速度与项目规模无关(50 个模块 vs 5000 个模块一样快)
裸模块处理:
浏览器无法识别 import React from 'react' 中的 react。Vite 使用 es-module-lexer 解析所有 import,重写为有效 URL:
js
// 源码
import React from 'react'
// Vite 重写后
import React from '/@fs/workspace/node_modules/.vite/deps/react.js'// 源码
import React from 'react'
// Vite 重写后
import React from '/@fs/workspace/node_modules/.vite/deps/react.js'2. 依赖预构建
虽然源码不打包,但第三方依赖需要特殊处理。原因:
| 问题 | 说明 |
|---|---|
| CJS/UMD 兼容 | npm 包大量使用 CommonJS,浏览器无法直接运行 |
| 请求数量过多 | lodash-es 有 600+ 文件,每个一个请求 |
| 模块格式不统一 | 需要统一转为 ESM |
预构建流程(使用 esbuild,Go 编写,比 JS 打包器快 10-100 倍):
- 扫描源码中的裸模块导入
- esbuild 将依赖合并为少量 ESM 文件
- 输出到
node_modules/.vite/deps/ - 根据 lockfile 哈希判断是否需要重建(强缓存)
仅在首次启动或依赖变更时触发
3. HMR(热更新)
核心流程:
文件修改
↓
① chokidar 监听文件变更
↓
② 确定受影响的模块边界
↓
③ 仅对变更文件按需编译
↓
④ WebSocket 推送更新消息给浏览器
↓
⑤ 客户端重新请求该模块 (?t=timestamp)
↓
⑥ 执行新模块 → hot.accept() 回调 → 局部替换文件修改
↓
① chokidar 监听文件变更
↓
② 确定受影响的模块边界
↓
③ 仅对变更文件按需编译
↓
④ WebSocket 推送更新消息给浏览器
↓
⑤ 客户端重新请求该模块 (?t=timestamp)
↓
⑥ 执行新模块 → hot.accept() 回调 → 局部替换HMR API:
js
if (import.meta.hot) {
// 接受自身更新
import.meta.hot.accept((newModule) => {
console.log('模块已更新:', newModule)
})
// 接受依赖更新
import.meta.hot.accept('./dependency.js', (newDep) => {
updateDependency(newDep)
})
// 清理副作用
import.meta.hot.dispose(() => {
clearInterval(timer)
})
}if (import.meta.hot) {
// 接受自身更新
import.meta.hot.accept((newModule) => {
console.log('模块已更新:', newModule)
})
// 接受依赖更新
import.meta.hot.accept('./dependency.js', (newDep) => {
updateDependency(newDep)
})
// 清理副作用
import.meta.hot.dispose(() => {
clearInterval(timer)
})
}Vite vs Webpack
性能对比
| 维度 | Vite | Webpack |
|---|---|---|
| 冷启动 | ~0.8s(按需编译) | 8-20s(全量打包) |
| HMR(JS) | < 100ms | 800ms - 1.2s |
| HMR(CSS) | < 50ms | ~1.8s |
| 内存占用 | ~480 MB | ~1.2 GB |
| 生产构建 | ~6.3s | ~18.5s |
| 打包体积 | ~465 KB(gzip) | ~480-809 KB(gzip) |
核心差异
| 方面 | Vite | Webpack |
|---|---|---|
| 开发策略 | 按需编译(ESM) | 全量打包 |
| 配置 | 开箱即用,配置简洁 | 高度可配,但繁重 |
| TS 支持 | 原生,内置 esbuild | 需 ts-loader 或 babel |
| CSS 预处理器 | 原生支持 | 需 loader |
| 代码分割 | Rollup/Rolldown 自动 | 需手动 splitChunks |
| 插件生态 | 兼容 Rollup 插件 | 自成一派 |
选型建议
选 Vite:
- 新项目(Vue 3、React 18+、Svelte、Solid)
- 仅支持现代浏览器
- 追求开发体验和迭代速度
选 Webpack:
- 大型存量项目,有大量自定义 Webpack 配置
- 需要 Module Federation(微前端)
- 需要兼容 IE11
Vite 8 + Rolldown(2026)
Vite 8 于 2026 年 3 月发布,引入 Rust 编写的 Rolldown 统一打包器:
- 双引擎合一:取代 esbuild(dev)+ Rollup(prod)架构
- 构建速度:生产构建 10-30× 提升(72s → 3s)
- 包体积:从 ~50 MB 降至 ~18 MB
- 插件兼容:99%+ Rollup 插件可继续使用
迁移要点:
build.rollupOptions→build.rolldownOptions
Cao Note