import { defineConfig, type Plugin } from 'vite'; import { readFileSync } from 'node:fs'; import { fileURLToPath } from 'node:url'; import { dirname, resolve } from 'node:path'; // 开发用 Vite dev server:提供 HMR,并把 API / 静态资源代理到本地 FastAPI(:8000)。 // 生产构建仍走 esbuild(npm run build)。 // // genesis-dev-html 插件:请求 '/' 时实时读取规范页面 // src/genesis/server/static/chat.html 并转换为开发入口(脚本指向 /src/main.ts、 // 去掉生产 CSS link 与版本占位),并注入 Vite HMR 客户端。 // 这样开发期不存在会过期的中间 HTML,改 chat.html 也会即时整页刷新。 const frontendDir = dirname(fileURLToPath(import.meta.url)); const chatHtmlPath = resolve(frontendDir, '../src/genesis/server/static/chat.html'); const VITE_CLIENT = ''; function devHtmlPlugin(): Plugin { const render = (): string => { let html = readFileSync(chatHtmlPath, 'utf8'); html = html .replace( /', ) .replace(/\s*/, '') .replace(/\?v=__ASSET_VER__/g, ''); return html.replace('', VITE_CLIENT + '\n'); }; return { name: 'genesis-dev-html', configureServer(server) { server.watcher.add(chatHtmlPath); server.watcher.on('change', (file) => { if (resolve(file) === chatHtmlPath) server.ws.send({ type: 'full-reload' }); }); server.middlewares.use((req, res, next) => { const url = (req.url || '').split('?')[0]; if (req.method !== 'GET' || (url !== '/' && url !== '/index.html')) return next(); res.setHeader('Content-Type', 'text/html; charset=utf-8'); res.end(render()); }); }, }; } export default defineConfig({ root: '.', plugins: [devHtmlPlugin()], server: { host: '127.0.0.1', port: 5173, proxy: { '/api': { target: 'http://127.0.0.1:8000', changeOrigin: true, ws: true }, '/static': { target: 'http://127.0.0.1:8000', changeOrigin: true }, }, }, });