一、Vite 是什么
Vite(法语"快"的意思)是由尤雨溪(Vue.js 作者)创建的下一代前端构建工具。它利用浏览器原生 ES Module 支持和现代 JavaScript 特性,提供极速的开发体验。
二、核心实现原理
1. 开发模式:基于原生 ESM 的按需编译
传统打包工具(如 Webpack)在开发时需要先把所有模块打包成 bundle 再启动服务器,项目越大启动越慢。
Vite 的做法完全不同:
- No-Bundle 策略:开发服务器启动时不打包任何代码,直接启动一个 HTTP 服务器。
- 浏览器原生 ESM 加载:浏览器通过
<script type="module">发起模块请求,Vite 拦截这些请求并按需编译返回。 - 请求拦截与转换:当浏览器请求
/src/App.vue时,Vite 实时将.vue文件编译为 JS 返回,只处理当前页面实际需要的模块。
xml
浏览器请求 index.html
→ <script type="module" src="/src/main.js">
→ import App from './App.vue'
→ Vite 拦截,实时编译 App.vue → 返回 JS
→ import Button from './Button.vue'
→ Vite 拦截,实时编译 Button.vue → 返回 JS
2. 依赖预构建(Dependency Pre-Bundling)
并非所有模块都适合原生 ESM 加载。node_modules 中的第三方库存在两个问题:
- CommonJS/UMD 格式:浏览器不支持,需要转换为 ESM
- 模块碎片化:如
lodash-es有 600+ 个子模块,逐个请求会导致网络瀑布流
Vite 使用 esbuild 进行依赖预构建:
- 在服务器启动前,用 esbuild(Go 编写,速度极快)将第三方依赖打包为单个 ESM 文件
- 预构建结果缓存在
node_modules/.vite中,依赖不变则无需重新构建 - 通过强缓存 HTTP 头(
max-age=31536000)避免重复请求
3. 热模块替换(HMR)
Vite 的 HMR 基于原生 ESM 实现:
- 精确更新:只需要使已编辑模块与其最近的 HMR 边界之间的链失活,大部分情况下只替换模块自身
- 速度恒定:无论项目多大,HMR 更新速度不会随之变慢(不像 Webpack 需要重新构建部分 bundle)
- 通过 WebSocket 通信:文件变更 → 服务器编译 → WebSocket 推送 → 浏览器精确替换模块
4. 生产构建:Rollup
开发环境用原生 ESM,但生产环境仍需打包(HTTP/2 下碎片化模块仍有开销)。Vite 生产构建使用 Rollup:
- Tree-shaking 更彻底
- 代码分割(Code Splitting)更智能
- 输出高度优化的静态资源
- 通过插件系统与开发模式保持行为一致
5. 插件系统
Vite 插件基于 Rollup 插件接口扩展,并增加了 Vite 特有的钩子:
javascript
// 一个简化的 Vite 插件示例
export default function myPlugin() {
return {
name: 'my-plugin',
// Rollup 通用钩子
resolveId(source) { /* 自定义模块解析 */ },
load(id) { /* 自定义模块加载 */ },
transform(code, id) { /* 代码转换 */ },
// Vite 独有钩子
configureServer(server) { /* 配置开发服务器 */ },
transformIndexHtml(html) { /* 转换 HTML */ },
handleHotUpdate(ctx) { /* 自定义 HMR 处理 */ },
}
}
三、核心架构图
scss
┌─────────────── 开发模式 ───────────────┐ ┌──── 生产模式 ────┐
│ │ │ │
│ 浏览器 ──ESM请求──→ Vite Dev Server │ │ Rollup 打包 │
│ │ │ │ + 插件链 │
│ ┌────────────┼────────────┐ │ │ + 压缩 │
│ │ │ │ │ │ + 分割 │
│ 源码按需编译 依赖预构建 HMR │ │ │ │
│ (esbuild) (esbuild) (WSS) │ │ │ → dist/ │
│ │ │ │ │ │ │
│ └────────────┴────────────┘ │ └───────────────────┘
└─────────────────────────────────────────┘
四、应用场景
| 场景 | 说明 |
|---|---|
| Vue/React/Svelte 项目 | 一等公民支持,开箱即用的模板和 HMR |
| 组件库开发 | Library Mode 支持打包为 ESM/UMD/CJS |
| SSR 应用 | 内建 SSR 支持,可配合 Nuxt 3 / Vite SSR |
| 微前端 | 与 Module Federation 或 qiankun 结合 |
| 多页应用 (MPA) | 支持多入口配置 |
| Electron 应用 | 配合 electron-vite 使用 |
五、性能优化策略
1. 构建优化
php
// vite.config.js
export default defineConfig({
build: {
// 手动代码分割 - 将大依赖单独打包
rollupOptions: {
output: {
manualChunks: {
vendor: ['react', 'react-dom'],
utils: ['lodash-es', 'dayjs'],
}
}
},
// 启用 CSS 代码分割
cssCodeSplit: true,
// 压缩方式:esbuild(快)或 terser(更小)
minify: 'esbuild',
// 设置 chunk 大小警告阈值
chunkSizeWarningLimit: 500,
}
})
2. 依赖优化
arduino
export default defineConfig({
optimizeDeps: {
// 强制预构建某些依赖(解决动态导入检测不到的问题)
include: ['esm-dep > cjs-dep', 'linked-package'],
// 排除不需要预构建的依赖
exclude: ['your-local-package'],
}
})
3. 按需加载与懒加载
javascript
// 路由级懒加载
const Home = () => import('./pages/Home.vue')
const About = () => import('./pages/About.vue')
// 组件级懒加载
import { defineAsyncComponent } from 'vue'
const HeavyChart = defineAsyncComponent(() => import('./HeavyChart.vue'))
4. 静态资源优化
arduino
export default defineConfig({
build: {
// 小于此大小的资源内联为 base64
assetsInlineLimit: 4096,
},
// 图片可配合 vite-plugin-imagemin 压缩
plugins: [
imagemin({ /* 配置 */ })
]
})
5. 开发体验优化
php
export default defineConfig({
server: {
// 预热常用文件,加速首次访问
warmup: {
clientFiles: ['./src/main.js', './src/App.vue'],
},
// 开启文件系统缓存
fs: { strict: false },
},
})
6. 使用 SWC / Lightning CSS 加速
javascript
// 使用 SWC 替代 Babel 转译(速度快 20-70 倍)
import react from '@vitejs/plugin-react-swc'
export default defineConfig({
plugins: [react()],
css: {
// 使用 Lightning CSS 替代 PostCSS(实验性)
transformer: 'lightningcss',
}
})
六、Vite vs Webpack 对比
| 维度 | Vite | Webpack |
|---|---|---|
| 冷启动 | 毫秒~秒级(不打包) | 秒~分钟级(全量打包) |
| HMR 速度 | 恒定快(ESM 精确更新) | 随项目增大而变慢 |
| 生产构建 | Rollup(Tree-shaking 优秀) | 自带打包(生态更成熟) |
| 配置复杂度 | 开箱即用,配置简洁 | 配置灵活但复杂 |
| 生态 | 快速增长中 | 最成熟的生态系统 |
| 底层语言 | esbuild(Go) + Rollup(JS) | 纯 JS |
七、总结
Vite 的核心创新在于将"打包"从开发流程中移除,利用浏览器原生 ESM + esbuild 的高性能实现了:
- 极速冷启动:无需等待打包,服务器瞬间启动
- 即时 HMR:模块级精确更新,速度与项目规模无关
- 高效生产构建:Rollup 提供优秀的 Tree-shaking 和代码分割
- 简洁的开发体验:合理的默认配置 + 强大的插件系统