Co-authored-by: pdf114514 <57948770+pdf114514@users.noreply.github.com> Agent-Logs-Url: https://github.com/pdf114514/CarReservation/sessions/6d0f25ae-6db4-4937-ae2b-6674456a5ca1
60 lines
1.7 KiB
JavaScript
60 lines
1.7 KiB
JavaScript
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 /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 /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 !== '/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,
|
|
proxy: {
|
|
'/api': {
|
|
target: backendOrigin,
|
|
changeOrigin: true,
|
|
},
|
|
},
|
|
},
|
|
});
|