import { defineConfig } from "vite"; import react from "@vitejs/plugin-react"; // Dev proxy targets the local GuruConnect (GC) server. `/api` and `/ws` are // forwarded to the Rust server on :3002 so `npm run dev` works against a real // backend without CORS gymnastics. // // PRODUCTION SERVING (wired in the GC server): // - `base` is "/" (absolute asset paths). The SPA is served from the server // root and uses `BrowserRouter`, so a hard reload of a deep link such as // `/machines` must still resolve `/assets/*` correctly. Relative ("./") // asset paths would break here: the browser would resolve them against the // deep-link path (`/machines/assets/...`) and 404. Absolute "/" is required. // - `build.outDir` points straight into the server's static tree at // `server/static/app/`, so `npm run build` lands the SPA exactly where the // Axum `fallback_service` serves it — no manual copy step at deploy time. // - `emptyOutDir` is true, which is SAFE because the target is the dedicated // `app/` SUBDIR. It wipes only `server/static/app/`, never the static root, // so the v1 portal files (login.html, dashboard.html, viewer.html, // downloads/) are untouched. const GC_SERVER = "http://localhost:3002"; export default defineConfig({ base: "/", plugins: [react()], server: { port: 5273, proxy: { "/api": { target: GC_SERVER, changeOrigin: true, }, "/ws": { target: GC_SERVER, changeOrigin: true, ws: true, }, }, }, build: { // Emit directly into the server's static tree. The Axum server serves this // directory as its SPA fallback (see server/src/main.rs). Dedicated subdir, // so emptyOutDir only clears the SPA build — not the v1 portal files. outDir: "../server/static/app", emptyOutDir: true, sourcemap: true, }, });