import { defineConfig, loadEnv } from 'vite' import vue from '@vitejs/plugin-vue' import viteCompression from 'vite-plugin-compression' import { viteMockServe } from 'vite-plugin-mock' import { fileURLToPath, URL } from 'url' // https://vitejs.dev/guide/env-and-mode.html#env-files export default defineConfig(({ mode, command }) => { const env = loadEnv(mode, process.cwd()) // mock 开关:仅 serve(dev)模式 + .env.local 里 VITE_USE_MOCK=true // 关掉时直接不注册 viteMockServe 插件(避免 mock routes 被注册) const useMock = command === 'serve' && env.VITE_USE_MOCK === 'true' return { plugins: [ vue(), // gzip 压缩 viteCompression(), // 本地 mock 服务(由 VITE_USE_MOCK 控制;prod / 关 mock 时不引入) ...(useMock ? [viteMockServe({ mockPath: 'mock', localEnabled: true, })] : []), ], base: env.VITE_RES_URL, resolve: { alias: { '@': fileURLToPath(new URL('./src', import.meta.url)) } }, css: { preprocessorOptions: { scss: { additionalData: `@use "@/style/mixin.scss" as *;` } } }, // ============================================================ // dev server proxy —— 本地多后端联调 // ============================================================ // ⚠️ 关键:proxy key 必须用 /api/ 后缀,避免拦截 SPA 路由 // 例如 /bookmark/api/v1/... → 8086(后端 API) // 但 /bookmark → 保留在前端(SPA 路由,由 history fallback 处理) // // 调试建议:浏览器开 Network,看 Server 响应头确认走了哪个后端 // // 端口对齐: // violin-auth: 8080 (context-path: /auth) // violin-calendar: 8085 (context-path: /calendar) // violin-bookmark: 8086 (context-path: /bookmark, 待你确认) // violin-onenote: 8087 (context-path: /onenote, 待你确认) // ... 新增服务时在这里加一行 server: { host: '0.0.0.0', port: 5173, proxy: { // auth: 业务 API 在 /api/v1/auth/...,没有 /auth/api 前缀 // 用 rewrite 把 /api/v1/auth/* 转成 /auth/api/v1/auth/* // 后端 context-path 是 /auth,所以请求路径需要带 /auth 前缀 '^/api/v1/auth/.*': { target: 'http://localhost:8080', changeOrigin: true, rewrite: (path) => path.replace(/^\/api\/v1\/auth/, '/auth/api/v1/auth'), }, // 其他服务:path 自带服务名前缀(/calendar/api/...) '^/calendar/api/.*': { target: 'http://localhost:8085', changeOrigin: true, }, '^/bookmark/api/.*': { target: 'http://localhost:8086', changeOrigin: true, }, '^/onenote/api/.*': { target: 'http://localhost:8087', changeOrigin: true, }, '^/trader/api/.*': { target: 'http://localhost:8088', changeOrigin: true, }, '^/traderCalender/api/.*': { target: 'http://localhost:8088', changeOrigin: true, }, '^/cloud/api/.*': { target: 'http://localhost:8089', changeOrigin: true, }, '^/wiki/api/.*': { target: 'http://localhost:8090', changeOrigin: true, }, }, }, build: { // 拆 chunk,减少首屏加载 rollupOptions: { output: { manualChunks: { 'vendor-vue': ['vue', 'vue-router', 'pinia'], 'vendor-ui': ['element-plus', '@element-plus/icons-vue'], 'vendor-chart': ['echarts'], } } } } } })