Files
sionrui/frontend/app/web-gold/vite.config.ts
2026-01-18 21:41:44 +08:00

118 lines
3.7 KiB
TypeScript

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