我为什么自己搭一个站
很多人问我为什么不直接用现成的博客平台。理由很简单:我想知道自己到底在写什么、数据存在哪里、页面是怎么发出去的。这个站就是答案。
先说结论
前台是纯静态的,后台是一个独立的单页应用,数据存在 Cloudflare D1,图片存在 R2,全部跑在 Cloudflare 的免费额度内。
三个决定构成了整个架构:
- 前台静态生成。访客打开的是 CDN 上的 HTML 文件,没有服务端渲染,没有数据库查询。快,而且便宜到几乎不花钱。
- 后台单独做。写作界面需要交互,那是编辑器该干的事;让它去影响读者加载的字节数是没道理的。
- 内容存起来,再重新生成。改一篇文章 = 写一次数据库 + 重建一次静态站。听起来原始,但换来的是前台可以做到零运行时依赖。
静态站不等于不能有后台
这是我最开始没想通的地方。静态站的问题是「内容改了要重新生成」,那只要解决「什么时候重新生成」就够了:
后台保存文章 → 写 D1 → 触发构建钩子 → Pages 重新构建 → 新内容上线
访客永远只碰静态文件,写作者永远只碰后台。两边的复杂度不会互相传染。
踩过的坑
无扩展名的 URL 会绕过响应头配置。 我在 _headers 里给 /*.html 设了不缓存,但 Pages 实际用的是 /posts/foo 这种没有扩展名的地址,规则根本匹配不到。结果是一篇删掉的文章在 CDN 上又活了七天。修法是给 /* 设默认值,再在具体规则里先清掉它。
多条 header 规则是合并,不是覆盖。 修上面那个问题时,我给 /* 加了 max-age=0,结果静态资源的响应头里同时出现了 max-age=0 和 immutable,浏览器取更严格的那个——等于所有 JS、CSS 都没缓存。得先在具体规则里用 ! Cache-Control 把全局值清掉。
本地构建读的是本地数据库。 我在自己电脑上点部署,发上去的是一堆演示数据。部署脚本必须显式从线上库取内容,否则这个错误永远静默。
部署分支搞错了会 404。 仓库没有 git remote 时,工具默认用 master 当分支名,于是部署落到预览环境,正式域名一直是 404。显式指定 main 才行。
这四个错的共同点是:本地全都测不出来。写代码的时候一切正常,只有真正部署到线上才会暴露。
成本
目前是零。免费额度对一个流量不大的个人站绰绰有余,真正稀缺的不是钱,是「改一次要多久」——现在改一篇文章,从保存到线上大约一分钟。
下一步
接下来想补三件事:把简历做成结构化数据(已经做了)、给每篇文章自动生成分享图、以及在内容多起来之后做全文搜索(搜索也是纯静态的索引,不占服务端)。
写这个站最大的收获不是学会了某个框架,而是终于搞清楚了一次请求从浏览器发出到页面出现在屏幕上,中间到底发生了什么。