平台工程

双部署目标的 base 路径陷阱 · 根路径拼出 //slug 全站内链失效

入档:2026-06-25 来源:蛛网之上(Astro 静态站)同时部署 GitHub Pages 子路径 + 香港服务器根路径,自定义域名站全站「关联文档」链接点击跳错 状态:已定位修复并上线验证(线上双斜杠内链 0 个)

一句话总结

一套代码部署到两个 base 不同的目标(Pages 子路径 /above-the-web vs 自定义域名根路径 /)时,凡是手动拼接 `${BASE}/${slug}` 的地方,在 BASE='/' 下会拼出 //slug——浏览器把 // 开头当成协议相对 URL(等价 https://slug),于是整站内链全跳错。而它只在根路径那个镜像现形,子路径镜像完全正常,极易漏测。

根因(决策链)

判据 / 排查法

修法

base 拼接归一化:先去掉 base 尾部斜杠再统一拼一个:

const BASE_PREFIX = BASE.endsWith('/') ? BASE.slice(0, -1) : BASE;
// 用 `${BASE_PREFIX}/${slug}/`,两种 base 都只得到单斜杠

注:框架自带的 import.meta.env.BASE_URL 已被归一化为总是以 / 结尾,所以用它的地方(${BASE_URL}slug)不会出 bug;只有自己读 process.env.BASE_PATH 手拼的地方才会踩。优先用框架归一化过的变量。

补充:markdown 正文里的站内互链走相对路径(2026-07-24 回验)

上面的归一化前提是能拿到 BASE_URL 变量。但内容集合的 markdown 正文(经 <Content/> 渲染)是静态文本,注入不了 import.meta.env.BASE_URL——于是正文里写站内链接有个双 base 死角:

解法:用相对路径,让浏览器按当前 URL 解析。 任务书详情页部署在 {base}/tasks/{slug}/,正文里写 [教程类任务规范](../spec/),浏览器以当前页 URL 为基准解析 ../spec/{base}/tasks/spec/——当前 URL 本就带着正确的 base,所以两种部署下都自动对,md 里一个字都不用改。

前提与判据:

教训(可复用)

  1. 多 base 部署 = 必须两个镜像都测链接。链接类 bug 会「只在一个镜像现形」,在另一个上验证会得出「没问题」的错误结论。—— 又一例「所见非真相」:看子路径镜像 ≠ 看根路径镜像。
  2. 本地复现根路径构建有坑:git-bash(MSYS)会把 BASE_PATH=/ 的值路径转换C:/Program Files/Git/,导致构建产物路径错乱。→ 用 PowerShell 设环境变量,或 MSYS_NO_PATHCONV=1
  3. 凡「环境变量可能为 /」的路径拼接,默认写归一化,不要裸 ${A}/${B}

关联文档

类型/平台工程