This repository has been archived on 2026-05-19. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
obsidian/DEV/VITE/配置详解.md
T
2026-04-20 22:47:51 +08:00

13 KiB

tags, create time
tags create time
DEV
VITE
configuration
typescript
2026-04-18

Vite 配置详解

配置文件结构

Vite 配置文件支持多种格式:vite.config.js、vite.config.ts,推荐使用 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 模块解析

路径别名

resolve: {
  alias: {
    '@': path.resolve(__dirname, './src'),
    // 支持目录别名
    '@components': path.resolve(__dirname, './src/components'),
    '@utils': path.resolve(__dirname, './src/utils')
  }
}

扩展名解析

resolve: {
  extensions: ['.js', '.jsx', '.ts', '.tsx', '.json']
}

server 开发服务器

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 环境变量

# .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
// 类型定义
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 构建配置

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 预览配置

preview: {
  port: 4173,
  strictPort: false,
  host: true,
  open: true,

  // 预览服务器配置
  cors: true,

  // 中间件
  middlewares: [
    // 自定义中间件
  ]
}

CSS 配置

CSS Modules

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 预处理器

css: {
  preprocessorOptions: {
    scss: {
      additionalData: `@import "@/styles/variables.scss";`,
      api: 'modern-compiler'        // 使用现代编译器
    },
    less: {
      modifyVars: {
        'primary-color': '#1890ff'
      },
      javascriptEnabled: true
    }
  }
}

PostCSS 配置

// postcss.config.js
export default {
  plugins: {
    autoprefixer: {},
    'cssnano': {
      preset: 'default'
    }
  }
}

插件系统

插件配置流程

graph TD
    A[vite.config.ts] --> B[插件导入]
    B --> C[插件配置]
    C --> D[插件注册]
    D --> E[构建流程]
    E --> F[插件执行]

官方插件

React 插件

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 插件

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
      }
    })
  ]
})

自定义插件

基础插件结构

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')
    }
  }
}

环境变量插件

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)
        }
      }
    }
  }
}

第三方插件推荐

路径别名插件

import { viteCommonjs } from '@originjs/vite-plugin-commonjs'

export default defineConfig({
  plugins: [
    react(),
    viteCommonjs()  // 支持 CommonJS 模块
  ]
})

压缩插件

import viteCompression from 'vite-plugin-compression'

export default defineConfig({
  plugins: [
    viteCompression({
      verbose: true,
      disable: false,
      threshold: 10240,
      algorithm: 'gzip',
      ext: '.gz'
    })
  ]
})

组件按需加载

import Components from 'unplugin-vue-components/vite'
import { AntDesignVueResolver } from 'unplugin-vue-components/resolvers'

export default defineConfig({
  plugins: [
    Components({
      resolvers: [
        AntDesignVueResolver()
      ]
    })
  ]
})

TypeScript 配置

tsconfig.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 配置文件提供类型)

{
  "compilerOptions": {
    "composite": true,
    "skipLibCheck": true,
    "module": "ESNext",
    "moduleResolution": "bundler",
    "allowSyntheticDefaultImports": true,
    "strict": true
  },
  "include": ["vite.config.ts"]
}

高级配置

多入口配置

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')
      }
    }
  }
})

库模式配置

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 配置

export default defineConfig({
  build: {
    ssr: true,                    // 启用 SSR
    outDir: 'dist/server',        // SSR 输出目录
    rollupOptions: {
      input: './src/entry-server.ts'
    }
  },
  server: {
    middlewareMode: 'ssr'         // SSR 模式
  }
})

配置最佳实践

环境分离

// vite.config.ts
export default defineConfig(({ mode }) => {
  return {
    plugins: [
      mode === 'development' ? devPlugin() : prodPlugin()
    ],
    server: mode === 'development' ? devServerConfig : {}
  }
})

配置复用

// 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'
  }
}

配置验证

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`)
      }
    })
  }
}

故障排查

配置加载问题

# 调试配置加载
DEBUG=vite:config npm run dev

# 检查配置语法
node -c vite.config.ts

路径解析问题

// 使用 debug 插件检查路径
import { defineConfig } from 'vite'

export default defineConfig({
  resolve: {
    alias: {
      'debug': require.resolve('debug')
    }
  }
})

插件冲突诊断

// 在插件开发中添加日志
export function debugPlugin() {
  return {
    name: 'debug-plugin',
    transform(code, id) {
      console.log('Transforming:', id)
      return null
    }
  }
}

配置是 Vite 项目的核心,合理的配置能显著提升开发体验和构建质量。根据项目规模和需求,逐步完善配置是最佳实践。

相关文档: