Skip to content

Commit 352e83c

Browse files
longsizhuogithub-actions[bot]
authored andcommitted
fix(site-url): 拿掉 prod 硬编码 fallback,env 缺失生产即抛错
之前 lib/site-url.ts 用 '?? "https://involutionhell.com"' 做兜底,违反 docs/architecture/frontend-backend-separation.md:96-103 "生产环境不做硬编码 fallback" 的约定。 在 preview/staging 漏配 NEXT_PUBLIC_SITE_URL 时会静默产出指向 prod 域的 sitemap/robots, 这正是文档警告的"漏配变静默错地址"。 新策略走 resolveSiteUrl(): - env 非空 → normalizeSiteUrl 返回 - NODE_ENV === 'production' 且 env 缺失 → throw,构建/启动失败(intentional) - 其它(dev/test)→ fallback http://localhost:3000(和 next start -p 3000、 OAuth 回调、next.config.mjs rewrites 的 localhost:3000 约定对齐) robots / sitemap 继续 import { SITE_URL },无变更。
1 parent a3f16b9 commit 352e83c

1 file changed

Lines changed: 32 additions & 10 deletions

File tree

lib/site-url.ts

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,16 @@
99
* `RAW_SITE_URL` / `SITE_URL` 逻辑,完全同形。抽到这里避免两边独立 drift —— 任何
1010
* 调整(比如以后加 trailing-slash 归一、加端口清洗、换 env 名)只改这一个地方。
1111
*
12-
* 注意:保留与原实现完全一致的语义,只换引用来源,不变值。sitemap.ts 的单元不变性
13-
* 依赖这一点。
14-
*/
15-
16-
/**
17-
* 原始 env 值,fallback 到生产域名。
18-
* 不直接 export —— 消费方只应该拿规范化后的 SITE_URL。
12+
* 关于 fallback(2026 年 Round 4 改):原实现用 `?? "https://involutionhell.com"`
13+
* 做生产兜底,违反 `docs/architecture/frontend-backend-separation.md:96-103` 的
14+
* "生产环境不做硬编码 fallback" 约定 —— 在 preview/staging 漏配 env 时会静默产出
15+
* 指向 prod 域的 sitemap/robots,典型的"漏配变静默错地址"失败模式。
16+
*
17+
* 新策略:
18+
* - 生产 (NODE_ENV === "production"):env 缺失 → 模块加载时抛错,构建/启动失败。
19+
* - 开发/测试:env 缺失 → fallback 到 http://localhost:3000(与 next start 默认端口
20+
* 和项目里 OAuth 回调、rewrites 的 localhost:3000 约定一致),保留本地联调无门槛。
1921
*/
20-
const RAW_SITE_URL =
21-
process.env.NEXT_PUBLIC_SITE_URL ?? "https://involutionhell.com";
2222

2323
/**
2424
* 规范化站点 URL:
@@ -35,7 +35,29 @@ export function normalizeSiteUrl(url: string): string {
3535
return withProto.replace(/\/+$/, "");
3636
}
3737

38+
/**
39+
* 解析并校验 NEXT_PUBLIC_SITE_URL。抽成函数纯粹为了把 "prod 必须有 / dev 可 fallback"
40+
* 逻辑集中在一处。模块加载时调用一次,结果赋给 SITE_URL。
41+
*/
42+
function resolveSiteUrl(): string {
43+
const raw = process.env.NEXT_PUBLIC_SITE_URL;
44+
if (raw && raw.trim().length > 0) {
45+
return normalizeSiteUrl(raw);
46+
}
47+
48+
if (process.env.NODE_ENV === "production") {
49+
// 故意抛错:漏配 env 时构建/启动直接失败,比静默产出指向错误域名的 sitemap 安全。
50+
throw new Error(
51+
"[lib/site-url] NEXT_PUBLIC_SITE_URL is required in production " +
52+
"(see docs/architecture/frontend-backend-separation.md:96-103).",
53+
);
54+
}
55+
56+
// dev / test:沿用项目里 localhost:3000 的约定(next start 默认端口、OAuth 回调、rewrites 都是 3000)。
57+
return "http://localhost:3000";
58+
}
59+
3860
/**
3961
* 模块加载时计算一次,给 robots / sitemap / 其它需要站点根的地方直接 import 用。
4062
*/
41-
export const SITE_URL = normalizeSiteUrl(RAW_SITE_URL);
63+
export const SITE_URL = resolveSiteUrl();

0 commit comments

Comments
 (0)