dc4e73f73a
TanStack Router file-based routes: - vite.config.ts: TanStackRouterVite plugin (target: react, autoCodeSplitting: true) before the React plugin. - .gitignore: src/routeTree.gen.ts (auto-generated). - src/lib/query-client.ts: module-level QueryClient singleton. - src/routes/__root.tsx: root route, QueryClientProvider, Suspense- wrapped router + query devtools (dev-only via import.meta.env.DEV). - src/routes/login.tsx: public route. validateSearch schema accepts optional redirect. LoginRoute wraps <LoginPage> with onAuthenticated navigating to redirect ?? '/'. - src/routes/_authed/route.tsx: pathless protected layout. beforeLoad redirects to /login on 'anonymous'; falls through on 'unknown' / 'authenticating' so hard reload doesn't flash the login page. - src/routes/_authed/index.tsx: placeholder home with sign-out button. Cross-tab logout effect bounces to /login on store transition. - src/App.tsx: replaced — now creates the router and renders <RouterProvider />. The interim status-branching logic from 1.6 is gone (the route tree handles it). - eslint.config.js: override for src/routes/** disabling react-refresh/only-export-components — TanStack Router's file-based pattern intentionally co-exports Route alongside components. Code-splitting working: login chunk 37KB, home + auth 17KB, card primitive 31KB, all loaded lazily; main bundle 353KB. Deviations: 1. No top-level useRequireAuth hook — per-page useEffect on store transitions is just as effective and only used in one place. 2. ESLint override for src/routes/** matches the existing pattern for src/ui/primitives/**. 3. Login page's auto-navigate effect from 1.6 is removed — the route wrapper owns navigation via onAuthenticated.
57 lines
1.9 KiB
TypeScript
57 lines
1.9 KiB
TypeScript
import path from 'node:path';
|
|
import { defineConfig, loadEnv } from 'vite';
|
|
import react from '@vitejs/plugin-react';
|
|
import tailwindcss from '@tailwindcss/vite';
|
|
import { TanStackRouterVite } from '@tanstack/router-plugin/vite';
|
|
|
|
// https://vite.dev/config/
|
|
export default defineConfig(({ mode }) => {
|
|
const env = loadEnv(mode, process.cwd(), 'VITE_');
|
|
const directusUrl = env.VITE_DEV_DIRECTUS_URL ?? 'http://localhost:8055';
|
|
const processorWsUrl = env.VITE_DEV_PROCESSOR_WS_URL ?? 'ws://localhost:8081';
|
|
// The WS proxy target needs the ws:// scheme; derive from the http(s) URL.
|
|
const directusWsUrl = directusUrl.replace(/^http(s?):\/\//, 'ws$1://');
|
|
|
|
return {
|
|
plugins: [
|
|
// Router plugin must run BEFORE @vitejs/plugin-react so the generated
|
|
// routeTree is in place when React's transform runs.
|
|
TanStackRouterVite({ target: 'react', autoCodeSplitting: true }),
|
|
react(),
|
|
tailwindcss(),
|
|
],
|
|
resolve: {
|
|
alias: {
|
|
'@': path.resolve(__dirname, './src'),
|
|
},
|
|
},
|
|
server: {
|
|
port: 5173,
|
|
proxy: {
|
|
// Directus REST + GraphQL. Strip /api prefix; SPA hits relative URLs.
|
|
'/api': {
|
|
target: directusUrl,
|
|
changeOrigin: true,
|
|
rewrite: (p) => p.replace(/^\/api/, ''),
|
|
},
|
|
// Directus business-plane WebSocket. Strip /ws-business; rewrite to
|
|
// Directus's actual /websocket path.
|
|
'/ws-business': {
|
|
target: directusWsUrl,
|
|
ws: true,
|
|
changeOrigin: true,
|
|
rewrite: (p) => p.replace(/^\/ws-business/, '/websocket'),
|
|
},
|
|
// Processor live-position WebSocket. Strip /ws-live; Processor binds
|
|
// bare (no path prefix) per the Phase 1.5 task spec.
|
|
'/ws-live': {
|
|
target: processorWsUrl,
|
|
ws: true,
|
|
changeOrigin: true,
|
|
rewrite: (p) => p.replace(/^\/ws-live/, ''),
|
|
},
|
|
},
|
|
},
|
|
};
|
|
});
|