在写完数据库系统第七章的 Markdown 后,我把它推上 GitHub,触发了 Vercel 的自动部署。但是迟迟没有在网站上看到文章更新,于是我开始了排查,首先是检查文章的fronttier,确认没有问题。然后我又检查了 Markdown 的语法,确认也没有问题。接着我又检查了 Vercel 的构建日志,发现构建成功了,但文章内容却没有更新。
于是我删除了文章所有内容有一次推送,此时成功了文章内容更新了,我本能地怀疑了是文章内容的问题,但其实不然。
第一次看到这个现象时,我最自然的怀疑是:
- 文章太长
- 某一段 Markdown 语法有问题
- 某个公式、代码块或者图片把页面渲染搞坏了
但这里有个思维误区:
“删掉正文后能成功显示”,并不等于“正文内容本身有错”。
它也可能表示:
线上部署产物其实还停留在“删掉正文之后的那个旧版本”。
这次真正的问题就在这里。
最终原因
根因不是文章太大,也不是正文语法坏了。
真正的原因是:
Vercel 恢复了上一次部署的 build cache,而构建命令使用的是普通
astro build,没有强制清理 Astro 的 content cache,导致最新文章内容没有真正进入新的部署产物。
也就是说:
- Vercel 确实拉到了最新提交
- 但 Astro 在构建时沿用了旧的内容缓存
- 结果线上生成出来的页面,实际上还是上一版“只有概述”的内容
所以会出现一种非常迷惑的现象:
- 日志看起来是“最新提交”
- 构建状态是“成功”
- 页面也确实存在
- 但正文却还是旧版本
排查时,最关键的证据有三条。
- 本地完整构建是正常的
本地对最新提交执行构建后,Chapter7 的 HTML 是完整的,正文、目录、字数统计都正常。
也就是说:
- Markdown 文件本身没坏
- Astro 在本地能正确读取这篇文章
所以问题不在正文内容本身。
- 线上页面其实对应的是旧产物
线上旧页面返回的 HTML 大小,和我本地构建“只有概述”的那个版本几乎完全一致。
而完整文章对应的 HTML 明显大很多。
这说明线上当时拿到的,不是最新完整正文的构建结果,而是旧版本页面。
- Vercel 日志里明确写了恢复 build cache
部署日志里能看到类似这样的信息:
Restored build cache from previous deployment这本身不是错误,但和普通 astro build 组合在一起,就可能把旧内容缓存带进新部署。
修复方法其实很直接:
把构建命令从:
astro build改成:
astro build --force--force 的作用是:
清掉 Astro 的 content layer / collection cache,强制全量重建。
我最后改了两处:
package.json- GitHub Actions 里的构建命令
这样无论是本地构建,还是 CI / Vercel 触发构建,都会先清 Astro 的内容缓存,再重新读取 Markdown。
修复后,线上 Chapter7 页面立刻恢复成完整正文。
这个问题和“文章太大”没有关系
所以以后即使是一篇很短的文章,只要刚好踩中同样的缓存路径,理论上也可能遇到类似现象。
优先检查:
- Vercel 是否恢复了上一次 deployment 的 build cache
- 构建命令是不是普通
astro build - 本地
astro build --force后是否能正常生成完整页面
如果本地 --force 正常,而线上旧内容不变,那基本就可以沿着缓存方向继续查了。