import { defineConfig, loadEnv } from 'vite' import { fileURLToPath, URL } from 'node:url' import tailwindcss from '@tailwindcss/vite' import process from 'node:process' import vue from '@vitejs/plugin-vue' import vueJsx from '@vitejs/plugin-vue-jsx' import vueDevTools from 'vite-plugin-vue-devtools' import UnoCSS from 'unocss/vite' import { compression, defineAlgorithm } from 'vite-plugin-compression2' import zlib from 'zlib' // 压缩配置常量 const COMPRESSION_THRESHOLD = 1024 // 环境变量默认值 const DEFAULT_ENV_VALUES = { DEV_TOKEN: '', TENANT_ID: '1', API_TARGET: 'http://localhost:9900', } export default defineConfig(({ mode }) => { const env = loadEnv(mode, process.cwd(), '') const DEV_TOKEN = env.VITE_DEV_TOKEN || DEFAULT_ENV_VALUES.DEV_TOKEN const TENANT_ID = env.VITE_TENANT_ID || DEFAULT_ENV_VALUES.TENANT_ID const API_TARGET = env.VITE_PROXY_TARGET || DEFAULT_ENV_VALUES.API_TARGET return { plugins: [ vue(), vueJsx(), UnoCSS(), vueDevTools(), tailwindcss(), // 压缩配置:同时生成 gzip 和 brotli 压缩文件 compression({ algorithms: [ defineAlgorithm('gzip', { level: 9 }), defineAlgorithm('brotliCompress', { params: { [zlib.constants.BROTLI_PARAM_QUALITY]: 11 } }) ], threshold: COMPRESSION_THRESHOLD, }), ], resolve: { alias: { '@': fileURLToPath(new URL('./src', import.meta.url)), '@gold': fileURLToPath(new URL('../../', import.meta.url)), }, }, server: { proxy: { '/webApi': { target: API_TARGET, changeOrigin: true, rewrite: (path: string) => path.replace(/^\/webApi/, ''), configure: (proxy: any) => { proxy.on('proxyReq', (proxyReq: any, req: any) => { const authHeader = req.headers?.authorization if (authHeader) { proxyReq.setHeader('authorization', authHeader) } else if (DEV_TOKEN) { proxyReq.setHeader('authorization', `Bearer ${DEV_TOKEN}`) } proxyReq.setHeader('tenant-id', TENANT_ID) }) }, }, '/oss': { target: 'https://muye-ai-chat.oss-cn-hangzhou.aliyuncs.com', changeOrigin: true, rewrite: (path: string) => path.replace(/^\/oss/, ''), headers: { 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS', 'Access-Control-Allow-Headers': '*', }, }, }, }, build: { // 生产环境去除 console 和 debugger esbuild: { drop: mode === 'production' ? ['console', 'debugger'] : [], }, // 使用 esbuild 压缩 minify: 'esbuild', // 关闭 source map 以减小体积 sourcemap: false, // 块大小警告阈值 chunkSizeWarningLimit: 1500, // 浏览器兼容性目标(使用最新的广泛支持版本) target: 'baseline-widely-available', // Rollup 配置优化 rollupOptions: { output: { // 手动代码分割 manualChunks: { // Vue 生态系统 'vue-vendor': ['vue', 'vue-router', 'pinia'], // UI 组件库 'ui-vendor': ['ant-design-vue', '@ant-design/icons-vue'], // 工具库 'utils': ['dayjs', 'qs', 'path-to-regexp'], // AI 相关 'ai-sdk': ['@ai-sdk/anthropic', '@ai-sdk/openai', 'ai'], // 文件处理 'file-tools': ['xlsx', 'xlsx-js-style'], }, }, }, }, } })