import { defineConfig } from 'vite'; import react from '@vitejs/plugin-react'; import { fileURLToPath } from 'node:url'; const root = fileURLToPath(new URL('../..', import.meta.url)); const p = (rel: string) => fileURLToPath(new URL(rel, import.meta.url)); /* * 稳定版(./stable.sh)用 `vite preview` 托 .build/stable 的静态文件。preview 有一道宿主校验 * (防 DNS rebinding),默认只放 localhost 与 IP —— 经域名 / 反代进来会被拦: * 「Blocked request. This host ("…") is not allowed.」 * 放哪些宿主由起它的人说(PREVIEW_ALLOWED_HOSTS,逗号分隔;`.example.com` 放整个子域;`*` 全放)。 * 开发那台 `vite` 不读这个,不受影响。 */ const previewHosts = process.env.PREVIEW_ALLOWED_HOSTS?.trim(); const preview = previewHosts === undefined || previewHosts === '' ? {} : { preview: { allowedHosts: previewHosts === '*' ? (true as const) : previewHosts .split(',') .map((s) => s.trim()) .filter((s) => s !== ''), }, }; export default defineConfig({ ...preview, plugins: [react()], resolve: { alias: { '@contracts': `${root}packages/contracts/src/index.ts`, '@sfeel': `${root}packages/sfeel/src/index.ts`, '@ui': `${root}packages/ui-kit/src/index.ts`, '@utils': `${root}packages/utils/src/index.ts`, '@features': p('./src/features'), '@web-shared': p('./src/shared'), '@contracts/': `${root}packages/contracts/src/`, }, }, server: { port: 5173, /* * 双栈全绑(host: true = `::` 双栈 any)。 * * 这坑栽过**两次**:不给 host 时只绑 `[::1]`,`127.0.0.1` 连不上; * 改绑 `127.0.0.1` 后 `[::1]` 又连不上 —— 单栈回环怎么绑都有一族是死的, * 浏览器把 localhost 解析到哪族全看系统心情,表现就是「时好时坏」。 * 回环双栈没有单 socket 的绑法,只能 any。 * * 代价说明白:这会暴露到局域网 —— 但 API 从来就是 `*:8787`(Node 默认双栈 any), * Web 跟它对齐并没有扩大暴露面;有登录门,且这是开发机。 * 要收回环,把这里改回 '127.0.0.1',并接受 [::1] 那族不通。 */ host: true, proxy: { /* * **默认连本机 API(:8787)**;要连测试服务器就显式给 `API_PROXY_TARGET=http://150.158.83.131:46100`。 * 从前反过来(默认远端、本地要覆盖):实测那条远端是一条**隧道回到本机 :8787**, * 浏览器的每一次请求都先出公网再绕回来 —— 能用,但慢,且隧道一断本地开发就整个瘫掉, * 而人只会看到「前端调的后端不太对」(2026-08-27)。CLAUDE.md 写的本地工作流是 * `pnpm dev:api` + `pnpm dev:web`,默认值就该服务于这条路;要远端的人自己说出来。 */ '/api': { target: process.env.API_PROXY_TARGET ?? 'http://127.0.0.1:8787', changeOrigin: true }, }, }, });