118 lines
3.7 KiB
TypeScript
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'],
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
})
|