数据截至 (上游 commit d1ac7f063d20)
agents.md 官网 — Next.js 源码走读
本章讲什么: 这一章走读 https://agents.md 的真实源码。它是个典型的 Next.js(Pages Router)+ Tailwind v4 静态营销站,代码不多,但有三个小而巧的工程点值得单独学。先给全景,再逐个拆。
全景:首页怎么拼出来
首页把一串内容区顺序拼起来(依据:pages/index.tsx:17-35):
<LandingPage>
Hero 标题 + 一个 AGENTS.md 代码块 + CTA
WhySection 为什么和 README 分开
CompatibilitySection ★ logo 跑马灯(§4.3)
ExamplesSection 宽代码块 + 例子仓库卡片(贡献者数,§4.1)
HowToUseSection 四步怎么用
AboutSection 治理/基金会
FAQSection 常见问答
Footer
数据只有一处:构建时抓取几个示例仓库的贡献者信息(getStaticProps),其余全是静态内容。下面三节挑出真正有工程含量的部分。
4.1 贡献者数:用分页响应头 Link 反推总数
要解决的小问题: 例子卡片想显示「openai/codex 有 N 位贡献者」。但 GitHub 的 /contributors API 不直接返回总数——它是分页的。逐页拉到底再数?对大仓可能是几十次请求,太贵。
思路/直觉: GitHub 分页会在响应的 Link 头里塞 rel="last" 指向最后一页的 URL。只要把每页大小设成 1(per_page=1),最后一页的页码 = 总条数。 于是一次请求 + 读一个响应头就拿到总数,不用翻页。
原理演示(示意,非源码):
// 每页只要 1 条,只为读 Link 头里的 last 页码
const res = await fetch(url + "?per_page=1&anon=1");
const link = res.headers.get("link");
// link 形如: <...&page=438>; rel="last"
const last = link.match(/&?page=(\d+)>; rel="last"/);
const total = last ? Number(last[1]) : 0; // 438 = 总贡献者数
// 重点看:总数是「最后一页页码」,不是把每页数据加起来
真实实现: 逻辑在 pages/index.tsx:114-131——取 link 头、正则 /&?page=(\d+)>; rel="last"/ 抠出末页码作为 total;没有 Link 头(说明只有一页)时退回数返回数组长度。头像另用 per_page=3 取前三个(pages/index.tsx:98-110)。
配套的省钱设计:
- 进程内内存缓存 + 12 小时窗口:同一个 Node 进程 12 小时内不重复打 GitHub,专门为了本地开发反复刷新时不撞未认证 API 的 60 次/小时限额(依据:
pages/index.tsx:40-76)。 - 可选鉴权头:有
GH_AUTH_TOKEN才加Authorization,避免塞空头被当未认证(依据:pages/index.tsx:87-94)。 - ISR:
revalidate: 60*60*24,生产环境每 24 小时后台再生成(依据:pages/index.tsx:158)。
坑/细节: 抓取全程 try/catch 兜底,任何仓库抓失败就填 { avatars: [], total: 0 },保证构建不因 GitHub 抽风而挂(依据:pages/index.tsx:141-144)。