Vite构建实战
# 03.Vite构建实战
Vite 为什么比 Webpack 快 10~100 倍?理解 ESM 原生模块 + esbuild 预构建 + Rollup 生产的"双引擎"架构。
# 1. 案例引入:一样的项目,截然不同的速度
# 同一个 Vue 3 + TS 项目(200+ 组件)
# Webpack Dev Server
npm run dev # 启动 12 秒
修改 App.vue # HMR 更新 2.8 秒 ← 大型项目更慢
# Vite
npm run dev # 启动 0.4 秒 ← 大项目也不怎么变
修改 App.vue # HMR 更新 0.03 秒 ← 恒快
Vite 不只是"快一点的 Webpack",它是完全不同的架构范式。
# 2. Vite 核心原理
# 2.1 Webpack 为什么慢
Webpack 开发模式:
所有源文件 → 打包成 Bundle → Dev Server → 浏览器加载
(入口文件 + 依赖递归) (整个项目) (一个几百 KB 的 bundle)
项目越大 → 模块越多 → 依赖图越复杂 → 打包越慢
修改一个文件 → 重新打包 → 重新加载 bundle → 慢
# 2.2 Vite 的快——零打包
Vite 开发模式:
Dev Server 启动 → 等待浏览器请求
↓
浏览器请求 main.ts
↓
Vite 拦截 → 编译单个 main.ts → 返回
↓ main.ts 内部 import { ref } from 'vue'
浏览器请求 vue 模块
↓
Vite 拦截 → 返回预构建好的 vue
↓ main.ts 内部 import App from './App.vue'
浏览器请求 App.vue
↓
Vite 拦截 → 编译单个 App.vue → 返回
核心差异:
Webpack:启动时把所有文件"做成一锅饭"
Vite: 来了客人再"按需炒菜"
# 2.3 双引擎架构
开发环境: 生产环境:
┌──────────────┐ ┌──────────────┐
│ 浏览器 ESM │ │ Rollup │
│ (原生模块) │ │ (打包器) │
└──────┬───────┘ └──────┬───────┘
│ 按需请求 │ 一次性打包
▼ ▼
单文件按需编译 所有文件统一打包
(esbuild 做转译) (Rollup 成熟稳定)
为什么开发用 esbuild,生产用 Rollup?
| 对比 | esbuild | Rollup |
|---|---|---|
| 速度 | 极快(Go 语言) | 快(JS 语言) |
| 生态 | 插件有限 | 丰富的 Rollup 插件 |
| 打包 | 不够成熟 | 多年验证的生产级打包 |
| 代码分割 | 弱 | 完善 |
| CSS 处理 | 有限 | 丰富 |
# 3. 配置文件详解
// vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { resolve } from 'path'
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { visualizer } from 'rollup-plugin-visualizer'
export default defineConfig({
// 1. 插件(大多数 Webpack Plugin 有对应的 Vite 版本)
plugins: [
vue(), // Vue SFC 编译
AutoImport({
imports: ['vue', 'vue-router', 'pinia'], // 自动导入 ref/computed 等
dts: 'src/auto-imports.d.ts' // 生成类型声明
}),
Components({
dts: 'src/components.d.ts' // 组件自动注册
}),
visualizer({ open: true }) // 打包体积分析
],
// 2. 路径别名
resolve: {
alias: {
'@': resolve(__dirname, 'src'),
'@components': resolve(__dirname, 'src/components'),
'@views': resolve(__dirname, 'src/views')
}
},
// 3. 开发服务器
server: {
port: 3000,
host: true,
open: true,
proxy: { // API 代理
'/api': {
target: 'http://localhost:8080',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, '')
}
}
},
// 4. 构建配置
build: {
outDir: 'dist',
sourcemap: false, // 生产不用 sourcemap
rollupOptions: {
output: {
manualChunks: { // 分包策略
'vue-vendor': ['vue', 'vue-router', 'pinia'],
'ui-vendor': ['element-plus']
}
}
},
chunkSizeWarningLimit: 1000 // KB
},
// 5. CSS 配置
css: {
preprocessorOptions: {
scss: {
additionalData: `@use "@/styles/variables.scss" as *;`
}
}
}
})
# 4. 依赖预构建——Vite 最核心的优化
# 4.1 为什么需要预构建
问题:import { ref } from 'vue'
vue 在 node_modules 下有 500+ 个内部模块文件
如果直接按需加载,浏览器要发 500+ 个 HTTP 请求——爆炸
Vite 的解决方案:预构建
1. 启动时扫描 node_modules 依赖
2. 将 500+ 个文件合并为少量 ESM 包
3. 浏览器只需请求 1~2 个文件
预构建过程:
node_modules/vue/
dist/vue.runtime.esm-bundler.js
packages/reactivity/src/...
packages/runtime-core/src/...
...500+ 个模块
↓ esbuild 打包
node_modules/.vite/deps/
vue.js (一个文件,包含所有 vue 模块)
# 4.2 自定义预构建
export default defineConfig({
optimizeDeps: {
include: ['lodash-es', 'dayjs'], // 强制预构建
exclude: ['your-local-package'], // 排除(开发中的本地包)
esbuildOptions: {
target: 'es2020' // 预构建目标
}
}
});
# 5. Vite vs Webpack:全维度对比
# 5.1 架构差异
Webpack:
Source → Bundle → Dev Server → 浏览器加载 bundle
所有模块都先打包,浏览器只加载一个(或几个)bundle
优点:成熟的打包策略
缺点:项目越大启动越慢
Vite:
Dev Server 启动 → 浏览器按需请求 → 单文件编译返回
不打包,利用浏览器原生 ESM
优点:启动和 HMR 极快
缺点:对 ESM 不支持的旧浏览器无效(但生产构建用 Rollup 可覆盖)
# 5.2 速度对比(200+ 组件项目)
| 指标 | Webpack 5 | Vite 5 | 倍数 |
|---|---|---|---|
| 冷启动 | 12~30s | 0.3~1.5s | 10~30× |
| HMR | 1~5s | <50ms | 20~100× |
| 生产构建 | 45~120s | 25~60s | 1.5~2× |
# 5.3 选型建议
你的场景?
├── 新项目(Vue 3 / React 18+)→ Vite(强烈推荐)
├── 旧项目维护(Vue 2 + Webpack 生态深绑定)→ 维持 Webpack
├── 需要兼容 IE11 → Webpack(Vite 不支持)
├── 微前端 / Module Federation → Webpack(Vite 当前较弱)
└── 组件库开发 → Vite(library mode 简单易用)
# 6. 环境变量
# .env # 所有环境
VITE_APP_TITLE=我的应用
# .env.development # npm run dev
VITE_API_URL=http://localhost:8080/api
# .env.production # npm run build
VITE_API_URL=https://api.example.com
// 使用
console.log(import.meta.env.VITE_API_URL)
console.log(import.meta.env.MODE) // 'development' | 'production'
console.log(import.meta.env.DEV) // true/false
console.log(import.meta.env.PROD) // true/false
// 类型声明
// env.d.ts
/// <reference types="vite/client" />
interface ImportMetaEnv {
readonly VITE_API_URL: string
}
注意:只有 VITE_ 前缀的变量才会暴露给前端代码——这是一种安全机制。
# 7. 构建优化
build: {
// 目标浏览器
target: 'es2020', // 现代浏览器默认
// 分包
rollupOptions: {
output: {
manualChunks: {
'vue-vendor': ['vue', 'vue-router'],
'vendor': ['lodash-es', 'dayjs']
}
}
},
// CSS 代码分割
cssCodeSplit: true,
cssMinify: 'lightningcss', // 比 cssnano 快 2~3×
// 压缩
minify: 'esbuild', // 或 'terser'
}
# 8. 速查表
| 特性 | Vite | Webpack |
|---|---|---|
| 冷启动** | < 1s | 10~30s |
| HMR** | < 50ms | 1~5s |
| 构建** | 快 | 较快 |
| 生态插件 | 快速增长 | 最丰富 |
| 学习曲线 | 低(零配置可用) | 中 |
| 旧浏览器 | 仅生产(Rollup) | 全链路支持 |
| 配置文件 | vite.config.ts | webpack.config.js |
| 核心原理 | ESM + esbuild + Rollup | 打包 + Loader/Plugin |
** 数值取决于项目规模
Vite 一句话:开发环境利用浏览器原生 ESM 实现零打包启动与毫秒级 HMR,生产环境用 Rollup 保证成熟稳定的打包质量。
下一篇:04.代码规范与质量
上次更新: 2026/06/24, 14:17:21