--- 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]] - 配置优化技巧