Axum now serves the v2 React/Vite dashboard SPA at / with a client-side routing fallback, and the dead v1 HTML portal is removed (nothing was live on the server to preserve). - SPA served from server/static/app via ServeDir with a fallback to index.html, so deep links (/machines, /sessions) resolve to the SPA. - /api/*rest and /ws/*rest return JSON 404 so unrouted API/WS paths never leak index.html to clients; real /api, /ws, /health, /metrics, and the /downloads nest keep precedence (matchit static-over-wildcard). - Path-aware Cache-Control: hashed /assets immutable, index.html no-cache. - Vite builds to server/static/app (base /); the artifact is gitignored and rebuilt at deploy time (npm ci && npm run build). - Removed v1 portal files (login/dashboard/users/index/viewer .html) and their dead serve_* handlers; the SPA owns /, /login, /dashboard, /users. Verified locally: server boots, / and deep links serve the SPA, unknown /api path returns JSON 404 (not HTML), /health and /downloads intact. cargo build + clippy -D warnings green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
49 lines
1.9 KiB
TypeScript
49 lines
1.9 KiB
TypeScript
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,
|
|
},
|
|
});
|