案例研究 4:一个不用你打理的内容站
想法
一位业余爱好者想把一个 Markdown 笔记文件夹——多年旅行积攒下来的餐厅点评——变成一个可搜索的公开站点,没有要登录的 CMS,也没有月度账单。加一条笔记,推送,搞定。
Spec
A static site generated from a folder of Markdown files, one file
per review (title, city, rating, body in frontmatter). Build a
homepage that lists reviews newest-first, a page per review, and
client-side search by city or name. No database, no login, no
build step I have to run by hand. Pushing a new .md file should
publish it.
隐藏的需求在最后一句里。"No build step I have to run by hand"意味着这段 spec 其实讲的是工作流,而不只是产物——而工作流需求正是那种你不点名 AI 就会跳过的类别,因为它们不会在跑起来的应用里露面。
技术栈
一个在构建时读取 Markdown 的静态站点生成器,部署到一个带 Git 触发构建的 CDN 托管平台上。推送到仓库,托管方重新构建,CDN 来分发。搜索在构建时生成的一个小 JSON 索引上做客户端搜索,所以没有服务器、也没有查询成本——在几百条点评这个量级上这是个不错的取舍,而且是我们点明了的、而非撞上的一个有意选择。
关键的 prompt
我们先把 AI 锚定在数据形状上,在任何 UI 之前:
Set up a static site that reads every .md file in /reviews. Each
file's frontmatter has title, city, rating (1-5), date. Parse all
of them at build time into a sorted list (newest first) and
generate: a homepage listing them, and one page per review at
/reviews/<slug>. Show me the data-loading code first, before any
styling.
"before any styling"是一根有意为之的杠杆。一次性把整个东西要过来,你会得到一个连着你信不过的数据、却很漂亮的页面;先把数据层要过来,你就能在哪怕一个像素分散你注意之前,先验证好地基。然后是搜索,被框住以保持廉价:
Generate a search.json at build time with {title, city, slug} for
every review. On the homepage, add a search box that filters the
visible list client-side by matching city or title — no network
calls, just filter the already-loaded index. Keep it under 50
lines of JS.
障碍
构建在本地通过了,但部署后的站点在每一个单独的点评页上都 404。首页能用;按点评分的页面不行。我们没去做推理,而是把症状和配置粘了上去:
Homepage works live, but /reviews/<slug> pages all 404 in
production while working in local dev. Here's my build output
directory listing and my host's deploy config: [pasted]. Why does
local dev serve these pages but production doesn't?
The AI traced it to the difference between dev-server routing (which
resolves paths dynamically) and static hosting (which serves only
files that physically exist). The build was generating the review
pages into the wrong output folder, so they never got uploaded —
dev had hidden the bug because its router faked the routes that
production couldn't.
我们把输出目录指向了托管方真正部署的那个,页面就出现了,并且我们在上线检查清单里加了一行:在线上站点点一个深层链接,而不只是首页。更广的教训是,"在 dev 里能用"和"部署后能用"是两个不同的主张,而静态导出恰恰就是这两者分道扬镳的地方——dev 服务器在路由上的宽容,是真正的基于文件的托管永远不会有的。
上线
我们推送了一条真实的点评,看着托管方重新构建,然后在线上域名加载了通向那一条具体点评的深层链接——也就是 dev 撒过谎的那个案例。然后我们搜了一下它的城市,确认索引把它收进来了。加下一条点评是一次一行的提交,而这正是全部意义所在:上线不是一个时刻,而是一个不用我们就能继续运转的工作流。