Update
This commit is contained in:
@@ -0,0 +1,695 @@
|
||||
---
|
||||
tags: [DEV, VITE, configuration, typescript]
|
||||
create time: 2026-04-18
|
||||
---
|
||||
|
||||
# Vite 配置详解
|
||||
|
||||
## 配置文件结构
|
||||
|
||||
Vite 配置文件支持多种格式:`vite.config.js`、`vite.config.ts`,推荐使用 TypeScript 获得类型提示。
|
||||
|
||||
完整配置结构示例:
|
||||
|
||||
```typescript
|
||||
import { defineConfig } from 'vite'
|
||||
import react from '@vitejs/plugin-react'
|
||||
import path from 'path'
|
||||
|
||||
export default defineConfig({
|
||||
// 插件配置
|
||||
plugins: [react()],
|
||||
|
||||
// 路径别名
|
||||
resolve: {
|
||||
alias: {
|
||||
'@': path.resolve(__dirname, './src'),
|
||||
'@components': path.resolve(__dirname, './src/components'),
|
||||
'@hooks': path.resolve(__dirname, './src/hooks')
|
||||
}
|
||||
},
|
||||
|
||||
// 开发服务器配置
|
||||
server: {
|
||||
port: 3000,
|
||||
host: true,
|
||||
open: true,
|
||||
cors: true
|
||||
},
|
||||
|
||||
// 构建配置
|
||||
build: {
|
||||
outDir: 'dist',
|
||||
sourcemap: true
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
## 核心配置项
|
||||
|
||||
### resolve 模块解析
|
||||
|
||||
#### 路径别名
|
||||
```typescript
|
||||
resolve: {
|
||||
alias: {
|
||||
'@': path.resolve(__dirname, './src'),
|
||||
// 支持目录别名
|
||||
'@components': path.resolve(__dirname, './src/components'),
|
||||
'@utils': path.resolve(__dirname, './src/utils')
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 扩展名解析
|
||||
```typescript
|
||||
resolve: {
|
||||
extensions: ['.js', '.jsx', '.ts', '.tsx', '.json']
|
||||
}
|
||||
```
|
||||
|
||||
### server 开发服务器
|
||||
|
||||
```typescript
|
||||
server: {
|
||||
// 端口配置
|
||||
port: 3000,
|
||||
strictPort: false, // 端口被占用时自动尝试下一个
|
||||
host: true, // 监听所有网络地址
|
||||
|
||||
// 自动打开浏览器
|
||||
open: true,
|
||||
openPage: '/dashboard',
|
||||
|
||||
// CORS 配置
|
||||
cors: true,
|
||||
|
||||
// 代理配置
|
||||
proxy: {
|
||||
'/api': {
|
||||
target: 'http://localhost:8080',
|
||||
changeOrigin: true,
|
||||
rewrite: (path) => path.replace(/^\/api/, '')
|
||||
},
|
||||
'/assets': {
|
||||
target: 'http://localhost:9000',
|
||||
changeOrigin: true
|
||||
}
|
||||
},
|
||||
|
||||
// HMR 配置
|
||||
hmr: {
|
||||
overlay: true, // 显示错误覆盖层
|
||||
port: 24678 // HMR WebSocket 端口
|
||||
},
|
||||
|
||||
// 中间件模式 (用于 SSR)
|
||||
middlewareMode: false
|
||||
}
|
||||
```
|
||||
|
||||
### load 环境变量
|
||||
|
||||
```bash
|
||||
# .env.development
|
||||
VITE_API_URL=http://localhost:8080/api
|
||||
VITE_APP_NAME=Dev Environment
|
||||
|
||||
# .env.production
|
||||
VITE_API_URL=https://api.example.com
|
||||
VITE_APP_NAME=Production
|
||||
```
|
||||
|
||||
```typescript
|
||||
// 类型定义
|
||||
interface ImportMetaEnv {
|
||||
readonly VITE_API_URL: string
|
||||
readonly VITE_APP_NAME: string
|
||||
}
|
||||
|
||||
// 使用环境变量
|
||||
const apiUrl = import.meta.env.VITE_API_URL
|
||||
const appName = import.meta.env.VITE_APP_NAME
|
||||
|
||||
// 自定义环境变量访问
|
||||
export default defineConfig(({ mode }) => {
|
||||
return {
|
||||
define: {
|
||||
__APP_VERSION__: JSON.stringify(process.env.npm_package_version),
|
||||
__ENV__: JSON.stringify(mode)
|
||||
}
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
### build 构建配置
|
||||
|
||||
```typescript
|
||||
build: {
|
||||
// 输出目录
|
||||
outDir: 'dist',
|
||||
assetsDir: 'assets',
|
||||
|
||||
// Source Map 配置
|
||||
sourcemap: false, // 生产环境关闭
|
||||
sourcemapExcludeSources: false,
|
||||
|
||||
// 压缩配置
|
||||
minify: 'terser', // terser | esbuild
|
||||
terserOptions: {
|
||||
compress: {
|
||||
drop_console: true, // 移除 console
|
||||
drop_debugger: true, // 移除 debugger
|
||||
pure_funcs: ['console.log', 'console.info']
|
||||
}
|
||||
},
|
||||
|
||||
// 代码分割配置
|
||||
rollupOptions: {
|
||||
output: {
|
||||
// 手动代码分割
|
||||
manualChunks: {
|
||||
'vendor-react': ['react', 'react-dom'],
|
||||
'vendor-ui': ['antd', '@ant-design/icons'],
|
||||
'vendor-utils': ['lodash', 'dayjs']
|
||||
},
|
||||
// 文件名模式
|
||||
chunkFileNames: 'js/[name]-[hash].js',
|
||||
entryFileNames: 'js/[name]-[hash].js',
|
||||
assetFileNames: '[ext]/[name]-[hash].[ext]'
|
||||
}
|
||||
},
|
||||
|
||||
// 构建优化
|
||||
chunkSizeWarningLimit: 1000, // 警告限制
|
||||
rollupOptions: {
|
||||
output: {
|
||||
// 内联动态导入
|
||||
inlineDynamicImports: false,
|
||||
// 保留模块结构
|
||||
preserveModules: false
|
||||
}
|
||||
},
|
||||
cssCodeSplit: true,
|
||||
reportCompressedSize: false,
|
||||
target: 'es2015'
|
||||
}
|
||||
```
|
||||
|
||||
### preview 预览配置
|
||||
|
||||
```typescript
|
||||
preview: {
|
||||
port: 4173,
|
||||
strictPort: false,
|
||||
host: true,
|
||||
open: true,
|
||||
|
||||
// 预览服务器配置
|
||||
cors: true,
|
||||
|
||||
// 中间件
|
||||
middlewares: [
|
||||
// 自定义中间件
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## CSS 配置
|
||||
|
||||
### CSS Modules
|
||||
```typescript
|
||||
css: {
|
||||
modules: {
|
||||
// 命名规范
|
||||
localsConvention: 'camelCase', // camelCase | camelCaseOnly | dashes | dashesOnly
|
||||
|
||||
// 作用域行为
|
||||
scopeBehaviour: 'local', // local | global
|
||||
|
||||
// 类名生成
|
||||
generateScopedName: '[name]__[local]___[hash:base64:5]',
|
||||
|
||||
// Hash 生成函数
|
||||
hashPrefix: 'prefix',
|
||||
|
||||
// 全局模块路径
|
||||
globalModulePaths: [/node_modules/]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### CSS 预处理器
|
||||
```typescript
|
||||
css: {
|
||||
preprocessorOptions: {
|
||||
scss: {
|
||||
additionalData: `@import "@/styles/variables.scss";`,
|
||||
api: 'modern-compiler' // 使用现代编译器
|
||||
},
|
||||
less: {
|
||||
modifyVars: {
|
||||
'primary-color': '#1890ff'
|
||||
},
|
||||
javascriptEnabled: true
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### PostCSS 配置
|
||||
```javascript
|
||||
// postcss.config.js
|
||||
export default {
|
||||
plugins: {
|
||||
autoprefixer: {},
|
||||
'cssnano': {
|
||||
preset: 'default'
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 插件系统
|
||||
|
||||
### 插件配置流程
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
A[vite.config.ts] --> B[插件导入]
|
||||
B --> C[插件配置]
|
||||
C --> D[插件注册]
|
||||
D --> E[构建流程]
|
||||
E --> F[插件执行]
|
||||
```
|
||||
|
||||
### 官方插件
|
||||
|
||||
#### React 插件
|
||||
```typescript
|
||||
import react from '@vitejs/plugin-react'
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [
|
||||
react({
|
||||
// Babel 转换
|
||||
babel: {
|
||||
plugins: ['emotion']
|
||||
},
|
||||
// JSX 运行时
|
||||
jsxRuntime: 'automatic', // classic | automatic
|
||||
// 开发工具
|
||||
devtools: true,
|
||||
// 包含
|
||||
include: /\.(jsx|js|tsx|ts)$/,
|
||||
// 排除
|
||||
exclude: /\.node_modules/
|
||||
})
|
||||
]
|
||||
})
|
||||
```
|
||||
|
||||
#### Vue 插件
|
||||
```typescript
|
||||
import vue from '@vitejs/plugin-vue'
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [
|
||||
vue({
|
||||
// Vue 编译器选项
|
||||
template: {
|
||||
compilerOptions: {
|
||||
isCustomElement: (tag) => tag.includes('-'),
|
||||
whitespace: 'condense'
|
||||
}
|
||||
},
|
||||
// 脚本配置
|
||||
script: {
|
||||
defineModel: true,
|
||||
propsDestructure: true
|
||||
},
|
||||
// 样式配置
|
||||
style: {
|
||||
scoped: true
|
||||
}
|
||||
})
|
||||
]
|
||||
})
|
||||
```
|
||||
|
||||
### 自定义插件
|
||||
|
||||
#### 基础插件结构
|
||||
```typescript
|
||||
import type { Plugin } from 'vite'
|
||||
|
||||
export function myCustomPlugin(): Plugin {
|
||||
return {
|
||||
name: 'my-custom-plugin',
|
||||
|
||||
// 配置阶段
|
||||
config(config) {
|
||||
return {
|
||||
// 返回配置修改
|
||||
}
|
||||
},
|
||||
|
||||
configResolved(config) {
|
||||
// 配置已解析
|
||||
console.log('Vite config resolved:', config)
|
||||
},
|
||||
|
||||
// 配置开发服务器
|
||||
configureServer(server) {
|
||||
// 自定义服务器中间件
|
||||
server.middlewares.use((req, res, next) => {
|
||||
if (req.url === '/custom-endpoint') {
|
||||
res.statusCode = 200
|
||||
res.setHeader('Content-Type', 'application/json')
|
||||
res.end(JSON.stringify({ message: 'Custom response' }))
|
||||
} else {
|
||||
next()
|
||||
}
|
||||
})
|
||||
|
||||
// 返回清理函数
|
||||
return () => {
|
||||
console.log('Server closed')
|
||||
}
|
||||
},
|
||||
|
||||
// 转换钩子
|
||||
transform(code, id) {
|
||||
// 转换代码
|
||||
if (id.endsWith('.custom')) {
|
||||
return {
|
||||
code: convertCustomFormat(code),
|
||||
map: null
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// 模块解析钩子
|
||||
resolveId(source) {
|
||||
// 自定义模块解析
|
||||
if (source === 'virtual-module') {
|
||||
return '\0virtual-module'
|
||||
}
|
||||
},
|
||||
|
||||
// 加载钩子
|
||||
load(id) {
|
||||
// 加载模块内容
|
||||
if (id === '\0virtual-module') {
|
||||
return 'export const msg = "Hello from virtual module"'
|
||||
}
|
||||
},
|
||||
|
||||
// 构建钩子
|
||||
buildStart() {
|
||||
console.log('Build started')
|
||||
},
|
||||
|
||||
buildEnd() {
|
||||
console.log('Build completed')
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 环境变量插件
|
||||
```typescript
|
||||
import type { Plugin } from 'vite'
|
||||
|
||||
export function envPlugin(): Plugin {
|
||||
return {
|
||||
name: 'env-plugin',
|
||||
config(config, { mode }) {
|
||||
// 加载环境变量
|
||||
const env = loadEnv(mode, process.cwd(), '')
|
||||
|
||||
return {
|
||||
define: {
|
||||
'import.meta.env': JSON.stringify(env)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 第三方插件推荐
|
||||
|
||||
#### 路径别名插件
|
||||
```typescript
|
||||
import { viteCommonjs } from '@originjs/vite-plugin-commonjs'
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [
|
||||
react(),
|
||||
viteCommonjs() // 支持 CommonJS 模块
|
||||
]
|
||||
})
|
||||
```
|
||||
|
||||
#### 压缩插件
|
||||
```typescript
|
||||
import viteCompression from 'vite-plugin-compression'
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [
|
||||
viteCompression({
|
||||
verbose: true,
|
||||
disable: false,
|
||||
threshold: 10240,
|
||||
algorithm: 'gzip',
|
||||
ext: '.gz'
|
||||
})
|
||||
]
|
||||
})
|
||||
```
|
||||
|
||||
#### 组件按需加载
|
||||
```typescript
|
||||
import Components from 'unplugin-vue-components/vite'
|
||||
import { AntDesignVueResolver } from 'unplugin-vue-components/resolvers'
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [
|
||||
Components({
|
||||
resolvers: [
|
||||
AntDesignVueResolver()
|
||||
]
|
||||
})
|
||||
]
|
||||
})
|
||||
```
|
||||
|
||||
## TypeScript 配置
|
||||
|
||||
### tsconfig.json
|
||||
```json
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2020",
|
||||
"useDefineForClassFields": true,
|
||||
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
||||
"module": "ESNext",
|
||||
"skipLibCheck": true,
|
||||
"moduleResolution": "bundler",
|
||||
"allowImportingTsExtensions": true,
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"noEmit": true,
|
||||
"jsx": "react-jsx",
|
||||
"strict": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@/*": ["src/*"]
|
||||
}
|
||||
},
|
||||
"include": ["src", "vite.config.ts"],
|
||||
"references": [{ "path": "./tsconfig.node.json" }]
|
||||
}
|
||||
```
|
||||
|
||||
### tsconfig.node.json (为 Vite 配置文件提供类型)
|
||||
```json
|
||||
{
|
||||
"compilerOptions": {
|
||||
"composite": true,
|
||||
"skipLibCheck": true,
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "bundler",
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"strict": true
|
||||
},
|
||||
"include": ["vite.config.ts"]
|
||||
}
|
||||
```
|
||||
|
||||
## 高级配置
|
||||
|
||||
### 多入口配置
|
||||
```typescript
|
||||
import { defineConfig } from 'vite'
|
||||
import path from 'path'
|
||||
|
||||
export default defineConfig({
|
||||
build: {
|
||||
rollupOptions: {
|
||||
input: {
|
||||
main: path.resolve(__dirname, 'index.html'),
|
||||
admin: path.resolve(__dirname, 'admin.html'),
|
||||
landing: path.resolve(__dirname, 'landing.html')
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
### 库模式配置
|
||||
```typescript
|
||||
export default defineConfig({
|
||||
build: {
|
||||
lib: {
|
||||
entry: path.resolve(__dirname, 'src/index.ts'),
|
||||
name: 'MyLibrary',
|
||||
fileName: (format) => `my-library.${format}.js`,
|
||||
formats: ['es', 'umd']
|
||||
},
|
||||
rollupOptions: {
|
||||
external: ['react', 'react-dom'],
|
||||
output: {
|
||||
globals: {
|
||||
react: 'React',
|
||||
'react-dom': 'ReactDOM'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
### SSR 配置
|
||||
```typescript
|
||||
export default defineConfig({
|
||||
build: {
|
||||
ssr: true, // 启用 SSR
|
||||
outDir: 'dist/server', // SSR 输出目录
|
||||
rollupOptions: {
|
||||
input: './src/entry-server.ts'
|
||||
}
|
||||
},
|
||||
server: {
|
||||
middlewareMode: 'ssr' // SSR 模式
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
## 配置最佳实践
|
||||
|
||||
### 环境分离
|
||||
```typescript
|
||||
// vite.config.ts
|
||||
export default defineConfig(({ mode }) => {
|
||||
return {
|
||||
plugins: [
|
||||
mode === 'development' ? devPlugin() : prodPlugin()
|
||||
],
|
||||
server: mode === 'development' ? devServerConfig : {}
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
### 配置复用
|
||||
```typescript
|
||||
// shared-config.ts
|
||||
export const baseConfig = {
|
||||
resolve: {
|
||||
alias: {
|
||||
'@': path.resolve(__dirname, './src')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const devConfig = {
|
||||
...baseConfig,
|
||||
server: {
|
||||
port: 3000
|
||||
}
|
||||
}
|
||||
|
||||
export const buildConfig = {
|
||||
...baseConfig,
|
||||
build: {
|
||||
outDir: 'dist'
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 配置验证
|
||||
```typescript
|
||||
function validateConfig(config: UserConfig) {
|
||||
if (!config.plugins) {
|
||||
throw new Error('Plugins are required')
|
||||
}
|
||||
|
||||
// 验证路径别名
|
||||
if (config.resolve?.alias) {
|
||||
Object.entries(config.resolve.alias).forEach(([key, value]) => {
|
||||
if (!path.isAbsolute(value)) {
|
||||
throw new Error(`Alias ${key} must be an absolute path`)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 故障排查
|
||||
|
||||
### 配置加载问题
|
||||
```bash
|
||||
# 调试配置加载
|
||||
DEBUG=vite:config npm run dev
|
||||
|
||||
# 检查配置语法
|
||||
node -c vite.config.ts
|
||||
```
|
||||
|
||||
### 路径解析问题
|
||||
```typescript
|
||||
// 使用 debug 插件检查路径
|
||||
import { defineConfig } from 'vite'
|
||||
|
||||
export default defineConfig({
|
||||
resolve: {
|
||||
alias: {
|
||||
'debug': require.resolve('debug')
|
||||
}
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
### 插件冲突诊断
|
||||
```typescript
|
||||
// 在插件开发中添加日志
|
||||
export function debugPlugin() {
|
||||
return {
|
||||
name: 'debug-plugin',
|
||||
transform(code, id) {
|
||||
console.log('Transforming:', id)
|
||||
return null
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
配置是 Vite 项目的核心,合理的配置能显著提升开发体验和构建质量。根据项目规模和需求,逐步完善配置是最佳实践。
|
||||
|
||||
相关文档:
|
||||
- [[DEV/VITE/架构原理.md]] - 理解配置的底层机制
|
||||
- [[DEV/VITE/优化实践.md]] - 配置优化技巧
|
||||
Reference in New Issue
Block a user