构建探针
一类检查:不看源码,只看构建出来的产物。
它和单元测试的分工很清楚:
| 问的问题 | 够不着的地方 | |
|---|---|---|
| 单元测试 | 这个函数算得对吗 | 它有没有被接进管线 |
| 构建探针 | 产物里真的是这样吗 | 为什么 |
为什么需要它#
因为有一整类 bug,单元测试永远抓不到:
- 配置写了但没接线(
@astrojs/mdx装了却没注册进integrations) - 文件写好了但没人引用(
fonts.css从头到尾没被 import) - 处理器换了 API(老写法被接受但不执行,只发一条弃用警告)
- 元素渲染了两遍(所有断言都问「存在吗」,没有一条问「出现几次」)
它们的共同点是:不报错、构建成功、测试全绿,只是没效果。
这个项目里的几条#
- 内容发布探针:真的放一个
.md与.mdx进去,构建,看能不能产出页面; 再放入草稿与占用/about/的文章,确认前者不会泄漏、后者会明确阻断构建。 读配置不够——配置可以是对的而接线是断的 - 链接渲染契约:正文里的
[[方括号]]是不是真的变成了链接 - 字体加载契约:
@font-face有没有进产物、字体总量有没有失控 - 区块唯一性:同一区块在一页里不得出现两次
- 子路径契约:六类载体(属性 / 脚本内路径 / 绝对 URL / 纯文本产物 / 内容清单 / NDJSON 全量导出)的 前缀是否都正确
一条纪律:新检查必须反向验证#
把 bug 放回去,确认它真的报错、退出码为 1。
这不是形式主义。这个项目里出现过三次「检查本身是坏的」, 而且失效方向是相反的:
- 漏检:一条检查因为
readdir在别的作用域、抛异常被 catch 吞掉, 扫了 0 个文件却报告「通过」 - 漏检:一条检查只匹配
href="/x"形式的相对绝对路径, 产物里https://开头的 URL 全部不进正则——于是「前缀翻倍」 这个致命问题在它的注视下安然通过 - 误报:还是那条检查。它后来改成对整段 HTML 跑正则来找属性,
于是正文里的代码示例也被当成链接——就是上一段里
href="/x"那个写法(它此刻正作为一个反例出现在这里)。修法是把正则锚定到 标签上,只认真正的属性:<[^>]*\s(?:href|src)="…"
误报和漏检一样有害:一条会红的检查,人第一反应是关掉它。
对模板尤其致命——使用者写一篇提到 href="/foo" 的文章,构建就失败,
而失败原因和他的文章毫无关系。
一条从没失败过的检查不值得信任; 一条会无缘无故变红的检查,同样不值得信任。
覆盖面要跟着「载体」走#
同一个地址可能出现在六类地方,而每类的写法不同:
href/src属性中的相对绝对路径<script>块里拼出来的路径(模板字符串拼的import()参数)https://开头的绝对 URL(og:image、RSS 发现、JSON-LD)- 纯文本产物里的链接(
llms.txt、robots.txt) - JSON 内容清单里的结构化 URL
- NDJSON 全量导出里每条记录的站点地址与内容 URL
每漏一类,就漏掉一整类 bug。 这些覆盖不是预先画出来的清单, 而是每次遇到真实漏检后补进契约的。
这一条指向(2)
已复核 · 2026-09-24
「已复核」指有人在上面那个日期读过这一页并确认了当时的正文。它不表示内容一定正确,也不表示每条引用的原文都逐句支持了这里的结论—— 后者只能由人判断。正文在那之后若被改动,复核会自动失效,构建会拦下来。
被这些页面引用(1)
这一页也有 markdown 版本:/letterpress/wiki/build-probe.md
直接打开上面的 .md 链接即可读取;在支持内容协商的部署平台上, 也可以对页面 URL 发送 Accept: text/markdown。