import {defineConfig} from "vite"; import react from "@vitejs/plugin-react"; import tailwindcss from "@tailwindcss/vite"; import path from "path"; // 需要安装 Node.js 的类型声明(@types/node) // https://vite.dev/config/ export default defineConfig({ plugins: [react(), tailwindcss()], resolve: { alias: { "@": path.resolve(__dirname, "./src"), // 将 @/ 映射到 src/ 目录 }, }, server: { host: "0.0.0.0", proxy: (() => { const pythonProxyConfig = { target: "http://localhost:18000", changeOrigin: true, secure: false, configure: (proxy: { on: (event: string, handler: (arg: unknown) => void) => void }) => { proxy.on("proxyReq", (proxyReq: unknown) => { (proxyReq as { removeHeader: (name: string) => void }).removeHeader("referer"); (proxyReq as { removeHeader: (name: string) => void }).removeHeader("origin"); }); proxy.on("proxyRes", (proxyRes: unknown) => { const res = proxyRes as { headers: Record }; delete res.headers["set-cookie"]; res.headers["cookies"] = ""; }); }, }; const javaProxyConfig = { target: "http://localhost:8080", changeOrigin: true, secure: false, configure: (proxy: { on: (event: string, handler: (arg: unknown) => void) => void }) => { proxy.on("proxyReq", (proxyReq: unknown) => { (proxyReq as { removeHeader: (name: string) => void }).removeHeader("referer"); (proxyReq as { removeHeader: (name: string) => void }).removeHeader("origin"); }); proxy.on("proxyRes", (proxyRes: unknown) => { const res = proxyRes as { headers: Record }; delete res.headers["set-cookie"]; res.headers["cookies"] = ""; }); }, }; // Python 服务: rag, synthesis, annotation, evaluation, models const pythonPaths = ["rag", "cleaning", "operators", "categories", "synthesis", "annotation", "knowledge-base", "data-collection", "evaluation", "models", "sys-param"]; // Java 服务: data-management, knowledge-base const javaPaths = ["data-management"]; const proxy: Record = {}; // SSE 端点需要禁用缓冲 proxy["/api/cleaning"] = { target: "http://localhost:32033", changeOrigin: true, secure: false, configure: (proxy: { on: (event: string, handler: (arg: unknown) => void) => void }) => { proxy.on("proxyReq", (proxyReq: unknown) => { (proxyReq as { removeHeader: (name: string) => void }).removeHeader("referer"); (proxyReq as { removeHeader: (name: string) => void }).removeHeader("origin"); }); proxy.on("proxyRes", (proxyRes: unknown) => { const res = proxyRes as { headers: Record }; delete res.headers["set-cookie"]; res.headers["cookies"] = ""; }); }, }; for (const p of pythonPaths) { proxy[`/api/${p}`] = pythonProxyConfig; } for (const p of javaPaths) { proxy[`/api/${p}`] = javaProxyConfig; } // ===== Casdoor SSO(M3) ===== // 注意代理键必须用 /sso(不是 /sso/casdoor),且 public/sso/callback.html 是静态文件, // 由 Vite 直接返回,不会命中 /sso 代理(代理只转发 API 前缀)。 proxy["/sso"] = javaProxyConfig; // /api/user/** 走网关自环路由(UserController / CasdoorOauthController 在网关本地)。 // 必须保留 Set-Cookie:CasdoorOauthController 依赖 casdoor_sso_state cookie 做 state 校验, // 仅对非 oauth 路径沿用删除 Set-Cookie 的旧行为。 proxy["/api/user"] = { target: "http://localhost:8080", changeOrigin: true, secure: false, configure: ( proxy: { on: (event: string, handler: (arg: unknown, arg2?: unknown) => void) => void; } ) => { proxy.on("proxyReq", (proxyReq: unknown) => { (proxyReq as { removeHeader: (name: string) => void }).removeHeader("referer"); (proxyReq as { removeHeader: (name: string) => void }).removeHeader("origin"); }); proxy.on("proxyRes", (proxyRes: unknown, req: unknown) => { const res = proxyRes as { headers: Record }; const url = (req as { url?: string })?.url ?? ""; if (!url.includes("/oauth/")) { delete res.headers["set-cookie"]; res.headers["cookies"] = ""; } }); }, }; // deepflow 后端(FastAPI :8000,路由在容器根 /api/*)。 // 剥离 /deepflow-backend 前缀:/deepflow-backend/api/config -> /api/config proxy["/deepflow-backend"] = { target: "http://localhost:8000", changeOrigin: true, secure: false, rewrite: (p: string) => p.replace(/^\/deepflow-backend/, ""), }; return proxy; })(), }, });