import { defineConfig } from 'vite'; import react from '@vitejs/plugin-react'; import net from 'net'; const backendOrigin = process.env.BACKEND_URL || 'http://localhost:3001'; /** * Custom Vite plugin that tunnels WebSocket upgrade requests at /api/ws to the * backend via raw TCP. Vite's built-in proxy `ws: true` can silently drop * upgrade events that Vite's own HMR handler intercepts first. This plugin * hooks directly onto `httpServer.upgrade` and handles the /api/ws path before * Vite gets a chance to claim it. */ function wsProxyPlugin() { return { name: 'ws-proxy', configureServer(server) { server.httpServer?.on('upgrade', (req, socket, head) => { if (req.url !== '/api/ws') return; const { hostname, port: rawPort } = new URL(backendOrigin); const port = parseInt(rawPort) || 3001; const conn = net.createConnection({ host: hostname, port }); conn.on('error', () => socket.destroy()); socket.on('error', () => conn.destroy()); conn.on('connect', () => { // Replay the original HTTP upgrade request to the backend const headers = `${req.method} ${req.url} HTTP/${req.httpVersion}\r\n` + Object.entries(req.headers) .map(([k, v]) => `${k}: ${v}`) .join('\r\n') + '\r\n\r\n'; conn.write(headers); if (head && head.length) conn.write(head); // Bidirectional pipe conn.pipe(socket).pipe(conn); }); }); }, }; } export default defineConfig({ plugins: [react(), wsProxyPlugin()], server: { port: 5173, allowedHosts: ["car.33-4.party"], proxy: { '/api': { target: backendOrigin, changeOrigin: true, }, }, }, });