expressを使うと楽に実装できた。
まだ試行錯誤しているので、とりあえずvite.config.tsにべた書き。
import { ViteDevServer, PluginOption, defineConfig } from 'vite' import react from '@vitejs/plugin-react-swc' import express from 'express'; import type { IncomingMessage, ServerResponse } from 'http'; import { request } from 'http'; function createReverseProxyHandler(path: string, proxyHost: string, proxyPort: number) { const handler = function(proxyReq: IncomingMessage, proxyRes: ServerResponse) { const serverReq = request({ host: proxyHost, port: proxyPort, method: proxyReq.method, path: proxyReq.url, headers: proxyReq.headers, }).on('error', () => { proxyRes.writeHead(502).end(); }).on('timeout', () => { proxyRes.writeHead(504).end(); }).on('response', serverRes => { proxyRes.writeHead(serverRes.statusCode!, serverRes.headers) serverRes.pipe(proxyRes); }) proxyReq.pipe(serverReq); } const router = express(); router.use(path, handler); return router; } function ReverseProxyPlugin(props: {path: string, proxyHost: string, proxyPort: number}): PluginOption { const { path, proxyHost, proxyPort } = props; return { name: 'ReverseProxyPlugin', configureServer(server: ViteDevServer) { server.middlewares.use(createReverseProxyHandler(path, proxyHost, proxyPort)); }, } as const satisfies PluginOption; } // https://vitejs.dev/config/ export default defineConfig({ plugins: [ react(), ReverseProxyPlugin({ path: '/api/', proxyHost: '127.0.0.1', proxyPort: 4000, }), ] })