Vite 配置
下一代前端构建工具的完整配置指南,从安装到企业级配置的全面覆盖。
快速开始
安装 Vite
创建新项目
bash
# 使用 npm
npm create vite@latest
# 使用 yarn
yarn create vite
# 使用 pnpm
pnpm create vite
# 使用 bun
bun create vite
指定项目名称和模板
bash
# Vue 项目
npm create vite@latest my-vue-app -- --template vue
yarn create vite my-vue-app --template vue
pnpm create vite my-vue-app --template vue
# React 项目
npm create vite@latest my-react-app -- --template react
yarn create vite my-react-app --template react
pnpm create vite my-react-app --template react
# TypeScript 版本
npm create vite@latest my-vue-app -- --template vue-ts
npm create vite@latest my-react-app -- --template react-ts
可用模板:
vanilla
,vanilla-ts
- 原生 JavaScriptvue
,vue-ts
- Vue.jsreact
,react-ts
- Reactpreact
,preact-ts
- Preactlit
,lit-ts
- Litsvelte
,svelte-ts
- Sveltesolid
,solid-ts
- Solidqwik
,qwik-ts
- Qwik
手动安装
bash
# 安装 Vite
npm install -D vite
yarn add -D vite
pnpm add -D vite
# 创建 index.html
echo '<p>Hello Vite!</p>' > index.html
# 启动开发服务器
npx vite
# 访问 http://localhost:5173
兼容性要求
- Node.js: 版本 20.19+ 或 22.12+
- 浏览器: 支持原生 ES 模块的现代浏览器
基础项目结构
my-vite-project/
├── index.html # 入口 HTML 文件
├── package.json # 项目配置
├── vite.config.js # Vite 配置文件
├── src/
│ ├── main.js # 应用入口
│ ├── App.vue # 根组件
│ └── components/ # 组件目录
└── public/ # 静态资源目录
🎯 分包策略配置
基础分包配置
javascript
// vite.config.js
export default defineConfig({
build: {
rollupOptions: {
output: {
manualChunks: {
// 框架核心
"vue-vendor": ["vue", "vue-router", "pinia"],
// UI 组件库
"ui-vendor": ["element-plus", "@element-plus/icons-vue"],
// 工具库
"utils-vendor": ["axios", "dayjs", "lodash-es"],
// 第三方库
"libs-vendor": ["echarts", "gsap"],
},
},
},
},
});
高级分包策略
javascript
// 动态分包 - 根据模块大小和使用频率
manualChunks(id) {
// 第三方库统一打包
if (id.includes('node_modules')) {
// 大型库单独分包
if (id.includes('echarts')) return 'echarts'
if (id.includes('element-plus')) return 'element-plus'
// 小型工具库合并
if (id.includes('dayjs') || id.includes('lodash')) return 'utils'
// 其他第三方库
return 'vendor'
}
// 业务模块分包
if (id.includes('/src/views/')) {
const module = id.split('/views/')[1].split('/')[0]
return `page-${module}`
}
}
使用场景与注意事项:
- 小项目:使用基础分包,减少配置复杂度
- 大型项目:使用动态分包,精确控制包大小
- 注意:过度分包会增加 HTTP 请求数,需要平衡包大小和请求数量
🎨 CSS 预处理器配置
Sass/SCSS 配置
javascript
export default defineConfig({
css: {
preprocessorOptions: {
scss: {
// 全局变量和混合宏自动导入
additionalData: `
@import "@/assets/styles/variables.scss";
@import "@/assets/styles/mixins.scss";
`,
// 使用现代编译器(推荐)
api: "modern-compiler",
},
},
},
});
PostCSS 配置
javascript
// 完整的 PostCSS 配置
css: {
postcss: {
plugins: [
// 自动添加浏览器前缀
require("autoprefixer")({
overrideBrowserslist: [
"Android 4.1",
"iOS 7.1",
"Chrome > 31",
"ff > 31",
"ie >= 8",
],
}),
// px 转 rem/vw(移动端适配)
require("postcss-px-to-viewport-8-plugin")({
viewportWidth: 375, // 设计稿宽度
unitPrecision: 5, // 转换精度
minPixelValue: 1, // 最小转换值
propBlackList: ["border-width"], // 不转换的属性
}),
];
}
}
CSS Modules 配置
javascript
css: {
modules: {
// 开发环境:可读性强的类名
// 生产环境:压缩的哈希类名
generateScopedName: process.env.NODE_ENV === "production"
? "[hash:base64:5]"
: "[name]__[local]__[hash:base64:5]";
}
}
使用场景与注意事项:
- 全局样式导入:适用于需要在所有组件中使用的变量和混合宏
- PostCSS 插件:根据项目需求选择,避免过度配置影响构建性能
- CSS Modules:适用于需要样式隔离的组件库或大型项目
🔗 路径别名配置
基础别名配置
javascript
import { resolve } from "path";
export default defineConfig({
resolve: {
alias: {
"@": resolve(__dirname, "src"),
"@/components": resolve(__dirname, "src/components"),
"@/views": resolve(__dirname, "src/views"),
"@/utils": resolve(__dirname, "src/utils"),
"@/api": resolve(__dirname, "src/api"),
"@/assets": resolve(__dirname, "src/assets"),
},
},
});
高级别名配置
javascript
// 动态路径解析函数
const pathResolve = (dir) => resolve(process.cwd(), '.', dir)
// 完整的别名配置
alias: {
// 基础路径
'@': pathResolve('src'),
'~': pathResolve('src'),
// 业务模块
'@/components': pathResolve('src/components'),
'@/views': pathResolve('src/views'),
'@/stores': pathResolve('src/stores'),
'@/composables': pathResolve('src/composables'),
'@/router': pathResolve('src/router'),
// 资源文件
'@/assets': pathResolve('src/assets'),
'@/images': pathResolve('src/assets/images'),
'@/styles': pathResolve('src/assets/styles'),
// 工具和配置
'@/utils': pathResolve('src/utils'),
'@/api': pathResolve('src/api'),
'@/config': pathResolve('src/config'),
'@/types': pathResolve('src/types')
}
TypeScript 支持
json
// tsconfig.json - 需要同步配置
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["src/*"],
"@/components/*": ["src/components/*"],
"@/views/*": ["src/views/*"]
}
}
}
使用场景与注意事项:
- 简化导入路径:避免
../../../
这样的相对路径 - 提高可维护性:重构时只需修改别名配置
- IDE 支持:配置 TypeScript 路径映射以获得智能提示
🌐 代理配置
基础代理配置
javascript
export default defineConfig({
server: {
proxy: {
// 代理所有 /api 请求
"/api": {
target: "http://localhost:8080",
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, ""),
},
},
},
});
多环境代理配置
javascript
// 根据环境变量配置不同的代理目标
const proxyTarget = {
development: 'http://localhost:8080',
test: 'https://test-api.example.com',
production: 'https://api.example.com'
}
server: {
proxy: {
'/api': {
target: proxyTarget[process.env.NODE_ENV] || proxyTarget.development,
changeOrigin: true,
secure: false, // 忽略 HTTPS 证书验证
rewrite: (path) => path.replace(/^\/api/, '')
},
// WebSocket 代理
'/ws': {
target: 'ws://localhost:8080',
ws: true,
changeOrigin: true
},
// 文件上传代理
'/upload': {
target: 'http://localhost:8080',
changeOrigin: true,
// 不重写路径,保持原始路径
}
}
}
高级代理配置
javascript
proxy: {
// 条件代理 - 根据请求头或参数决定代理目标
'/api': {
target: 'http://localhost:8080',
changeOrigin: true,
configure: (proxy, options) => {
proxy.on('proxyReq', (proxyReq, req, res) => {
// 添加自定义请求头
proxyReq.setHeader('X-Forwarded-Host', req.headers.host)
})
proxy.on('proxyRes', (proxyRes, req, res) => {
// 处理响应
console.log('代理响应:', req.url, proxyRes.statusCode)
})
}
}
}
使用场景与注意事项:
- 开发环境跨域:解决前后端分离开发中的跨域问题
- 多服务代理:不同 API 路径代理到不同的后端服务
- HTTPS 问题:设置
secure: false
忽略自签名证书 - WebSocket:需要设置
ws: true
支持 WebSocket 连接
📁 静态资源配置
基础资源配置
javascript
export default defineConfig({
build: {
// 静态资源目录
assetsDir: "assets",
// 小于 4KB 的资源内联为 base64
assetsInlineLimit: 4096,
rollupOptions: {
output: {
// 资源文件命名规则
assetFileNames: (assetInfo) => {
const extType = assetInfo.name.split(".").pop();
// 根据文件类型分类存放
if (/png|jpe?g|gif|svg|webp/i.test(extType)) {
return "assets/images/[name]-[hash].[ext]";
}
if (/woff2?|eot|ttf|otf/i.test(extType)) {
return "assets/fonts/[name]-[hash].[ext]";
}
if (/mp4|webm|ogg|mp3|wav|flac|aac/i.test(extType)) {
return "assets/media/[name]-[hash].[ext]";
}
return "assets/[name]-[hash].[ext]";
},
},
},
},
});
公共资源配置
javascript
// public 目录下的文件会被直接复制到输出目录
// 访问方式:/favicon.ico(不需要 /public 前缀)
// 在代码中引用 public 资源
const logoUrl = "/logo.png"; // public/logo.png
// 动态导入资源
const getImageUrl = (name) => {
return new URL(`../assets/images/${name}`, import.meta.url).href;
};
CDN 配置
javascript
// 生产环境使用 CDN
const isCDN = process.env.NODE_ENV === "production";
export default defineConfig({
base: isCDN ? "https://cdn.example.com/my-app/" : "/",
build: {
rollupOptions: {
external: isCDN ? ["vue", "vue-router"] : [],
output: {
globals: isCDN
? {
vue: "Vue",
"vue-router": "VueRouter",
}
: {},
},
},
},
});
使用场景与注意事项:
- 资源分类:按类型组织静态资源,便于管理和缓存策略
- 内联限制:小文件内联减少 HTTP 请求,大文件独立加载
- CDN 部署:生产环境使用 CDN 加速资源加载
- 缓存策略:文件名包含哈希值,支持长期缓存
🔌 插件加载与使用
Vue 生态插件
javascript
import vue from "@vitejs/plugin-vue";
import vueJsx from "@vitejs/plugin-vue-jsx";
export default defineConfig({
plugins: [
// Vue 单文件组件支持
vue({
// 自定义块支持
customElement: true,
// 模板编译选项
template: {
compilerOptions: {
// 将自定义元素视为原生标签
isCustomElement: (tag) => tag.startsWith("my-"),
},
},
}),
// JSX 支持
vueJsx({
// 启用优化
optimize: true,
}),
],
});
UI 组件库插件
javascript
// Element Plus 按需导入
import { ElementPlusResolver } from "unplugin-vue-components/resolvers";
import Components from "unplugin-vue-components/vite";
import AutoImport from "unplugin-auto-import/vite";
plugins: [
// 组件自动导入
Components({
resolvers: [ElementPlusResolver()],
// 自定义组件目录
dirs: ["src/components"],
// 生成类型声明文件
dts: true,
}),
// API 自动导入
AutoImport({
resolvers: [ElementPlusResolver()],
imports: ["vue", "vue-router", "pinia"],
dts: true,
}),
];
开发工具插件
javascript
// 开发环境增强插件
const devPlugins = [
// Mock 数据
viteMockServe({
mockPath: "mock",
localEnabled: true,
}),
// ESLint 检查
eslint({
include: ["src/**/*.{js,vue,ts}"],
exclude: ["node_modules"],
}),
];
// 生产环境优化插件
const prodPlugins = [
// 包分析
visualizer({
filename: "dist/stats.html",
open: true,
}),
// Gzip 压缩
viteCompression({
algorithm: "gzip",
}),
];
plugins: [...basePlugins, ...(isDev ? devPlugins : prodPlugins)];
使用场景与注意事项:
- 按需加载:使用 unplugin 系列插件实现组件和 API 的按需导入
- 开发体验:开发环境启用 Mock、ESLint 等工具提升开发效率
- 生产优化:生产环境启用压缩、分析等插件优化构建结果
- 插件顺序:某些插件对顺序敏感,需要注意配置顺序
📦 自动导入功能
API 自动导入
javascript
/**
* UI 组件相关插件配置
*/
import AutoImport from "unplugin-auto-import/vite";
import Components from "unplugin-vue-components/vite";
import { ElementPlusResolver } from "unplugin-vue-components/resolvers";
import Icons from "unplugin-icons/vite";
import IconsResolver from "unplugin-icons/resolver";
/**
* 创建 UI 相关插件
* @returns {Array} 插件数组
*/
export function createUIPlugins() {
return [
// API 自动导入
AutoImport({
imports: ["vue", "vue-router", "pinia"],
resolvers: [
ElementPlusResolver(),
IconsResolver({
prefix: "Icon",
}),
],
dts: false,
eslintrc: {
enabled: true,
filepath: "./.eslintrc-auto-import.json",
globalsPropValue: true,
},
}),
// 组件自动导入
Components({
resolvers: [
ElementPlusResolver({
importStyle: "sass",
}),
IconsResolver({
enabledCollections: [
"ep",
"tabler",
"svg-spinners",
"material-icon-theme",
"i-svg-spinners",
"majesticons",
],
}),
],
dts: true,
include: [/\.vue$/, /\.vue\?/],
}),
Icons({
autoInstall: true,
}),
];
}
// 需要下载图标集 @iconify/json
// 使用方式:<i-ep-arrow-left />
// <el-icon><i-tabler-arrow-left /></el-icon>
使用场景与注意事项:
- 减少样板代码:无需手动导入常用的 Vue API 和组件
- 类型支持:生成 TypeScript 声明文件保证类型安全
- ESLint 配置:需要配置 ESLint 识别自动导入的变量
- 构建优化:只导入实际使用的代码,支持 Tree Shaking
⚡ 性能优化配置
构建性能优化
javascript
export default defineConfig({
build: {
// 使用 esbuild 压缩(比 terser 快 10-20x)
minify: "esbuild",
// 禁用 gzip 大小报告(提升构建速度)
reportCompressedSize: false,
// 调整 chunk 大小警告限制
chunkSizeWarningLimit: 1000,
rollupOptions: {
// 并行处理
maxParallelFileOps: 5,
// 外部化依赖(CDN 场景)
external: ["vue", "vue-router"],
output: {
// 手动分包优化
manualChunks: {
"vue-vendor": ["vue", "vue-router", "pinia"],
"ui-vendor": ["element-plus"],
"utils-vendor": ["axios", "dayjs"],
},
},
},
},
});
依赖预构建优化
javascript
optimizeDeps: {
// 强制预构建
include: [
'vue',
'vue-router',
'pinia',
'element-plus/es',
'axios'
],
// 排除预构建
exclude: [
'your-local-package'
],
// 强制重新预构建
force: true,
// ESM 互操作
needsInterop: [
'element-plus'
]
}
开发服务器优化
javascript
server: {
// 预热文件
warmup: {
clientFiles: [
'./src/components/**/*.vue',
'./src/utils/**/*.js'
]
},
// 文件系统缓存
fs: {
// 允许访问的文件
allow: ['..'],
// 严格模式
strict: false
}
}
生产环境优化
javascript
// 条件配置
const isProduction = process.env.NODE_ENV === "production";
export default defineConfig({
esbuild: {
// 生产环境移除 console 和 debugger
drop: isProduction ? ["console", "debugger"] : [],
},
build: {
// 生产环境禁用 source map
sourcemap: !isProduction,
// CSS 代码分割
cssCodeSplit: true,
// 资源内联限制
assetsInlineLimit: 4096,
},
});
性能优化建议:
- 构建工具:使用 esbuild 替代 terser 进行代码压缩
- 依赖管理:合理配置预构建,避免重复构建
- 代码分割:按需分包,避免单个包过大
- 缓存策略:利用文件哈希实现长期缓存
- 开发体验:使用预热和缓存提升开发服务器启动速度
🛠️ 完整配置示例
基础项目配置
javascript
// vite.config.js
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import { resolve } from "path";
export default defineConfig({
plugins: [vue()],
resolve: {
alias: {
"@": resolve(__dirname, "src"),
},
},
server: {
port: 3000,
proxy: {
"/api": {
target: "http://localhost:8080",
changeOrigin: true,
},
},
},
build: {
outDir: "dist",
sourcemap: false,
rollupOptions: {
output: {
manualChunks: {
vendor: ["vue", "vue-router"],
},
},
},
},
});
企业级项目配置
javascript
// vite.config.js
import { defineConfig, loadEnv } from "vite";
import vue from "@vitejs/plugin-vue";
import AutoImport from "unplugin-auto-import/vite";
import Components from "unplugin-vue-components/vite";
import { ElementPlusResolver } from "unplugin-vue-components/resolvers";
import { resolve } from "path";
export default defineConfig(({ command, mode }) => {
const env = loadEnv(mode, process.cwd(), "");
const isProduction = mode === "production";
return {
plugins: [
vue(),
AutoImport({
imports: ["vue", "vue-router", "pinia"],
resolvers: [ElementPlusResolver()],
dts: true,
}),
Components({
resolvers: [ElementPlusResolver()],
dts: true,
}),
],
resolve: {
alias: {
"@": resolve(__dirname, "src"),
"@/components": resolve(__dirname, "src/components"),
"@/utils": resolve(__dirname, "src/utils"),
},
},
css: {
preprocessorOptions: {
scss: {
additionalData: '@import "@/assets/styles/variables.scss";',
},
},
},
server: {
host: "0.0.0.0",
port: 3000,
proxy: {
"/api": {
target: env.VITE_API_BASE_URL,
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, ""),
},
},
},
build: {
outDir: "dist",
sourcemap: !isProduction,
minify: "esbuild",
rollupOptions: {
output: {
manualChunks: {
"vue-vendor": ["vue", "vue-router", "pinia"],
"ui-vendor": ["element-plus"],
"utils-vendor": ["axios", "dayjs", "lodash-es"],
},
chunkFileNames: "assets/js/[name]-[hash].js",
entryFileNames: "assets/js/[name]-[hash].js",
assetFileNames: "assets/[ext]/[name]-[hash].[ext]",
},
},
},
optimizeDeps: {
include: ["vue", "vue-router", "pinia", "element-plus/es"],
},
};
});
🚨 常见问题与解决方案
构建问题
问题:构建时内存溢出
javascript
// 解决方案:调整 Node.js 内存限制
// package.json
{
"scripts": {
"build": "node --max-old-space-size=4096 ./node_modules/vite/bin/vite.js build"
}
}
// 或者优化构建配置
build: {
rollupOptions: {
maxParallelFileOps: 2, // 减少并行处理数量
},
reportCompressedSize: false // 禁用压缩大小报告
}
问题:依赖预构建失败
javascript
// 解决方案:手动配置依赖优化
optimizeDeps: {
force: true, // 强制重新预构建
include: [
'problematic-package' // 手动包含问题包
],
exclude: [
'problematic-package' // 或者排除问题包
]
}
开发问题
问题:热更新不生效
javascript
// 解决方案:检查文件监听配置
server: {
watch: {
usePolling: true, // 在某些系统上启用轮询
interval: 1000
}
}
问题:代理不工作
javascript
// 解决方案:检查代理配置
proxy: {
'/api': {
target: 'http://localhost:8080',
changeOrigin: true, // 必须设置
secure: false, // HTTPS 环境下设置
configure: (proxy) => {
proxy.on('error', (err) => {
console.log('代理错误:', err)
})
}
}
}
性能问题
问题:首次启动慢
javascript
// 解决方案:优化依赖预构建
optimizeDeps: {
include: [
// 预先包含大型依赖
'element-plus/es',
'echarts',
'lodash-es'
]
},
server: {
warmup: {
// 预热常用文件
clientFiles: ['./src/main.js', './src/App.vue']
}
}
💡 最佳实践总结
项目结构建议
src/
├── assets/ # 静态资源
│ ├── images/
│ ├── styles/
│ └── fonts/
├── components/ # 公共组件
│ ├── base/ # 基础组件
│ └── business/ # 业务组件
├── views/ # 页面组件
├── composables/ # 组合式函数
├── utils/ # 工具函数
├── api/ # API 接口
├── stores/ # 状态管理
├── router/ # 路由配置
└── types/ # 类型定义
配置文件组织
javascript
// 推荐:模块化配置
// vite.config.js
import { defineConfig } from "vite";
import { createPlugins } from "./build/plugins";
import { createAlias } from "./build/alias";
import { createProxy } from "./build/proxy";
export default defineConfig(({ command, mode }) => {
return {
plugins: createPlugins({ command, mode }),
resolve: { alias: createAlias() },
server: { proxy: createProxy() },
// ... 其他配置
};
});
环境变量管理
bash
# .env.development
VITE_API_BASE_URL=http://localhost:8080
VITE_APP_TITLE=开发环境
# .env.production
VITE_API_BASE_URL=https://api.example.com
VITE_APP_TITLE=生产环境
性能优化清单
- ✅ 使用 esbuild 进行代码压缩
- ✅ 合理配置代码分割策略
- ✅ 启用 Gzip/Brotli 压缩
- ✅ 优化静态资源处理
- ✅ 配置合适的缓存策略
- ✅ 使用 CDN 加速资源加载
- ✅ 启用依赖预构建优化
- ✅ 配置文件预热提升启动速度
开发体验优化
- ✅ 配置热重载和文件监听
- ✅ 设置代理解决跨域问题
- ✅ 使用自动导入减少样板代码
- ✅ 配置路径别名简化导入
- ✅ 集成 ESLint 和 Prettier
- ✅ 配置 TypeScript 类型检查
- ✅ 使用 Mock 数据进行开发
总结:这份配置指南涵盖了 Vite 的核心配置项,按功能分类便于快速查找。每个配置都包含了使用场景说明和注意事项,帮助你根据项目需求选择合适的配置方案。