建站记:为什么我选择 Astro + Cloudflare Pages

建站AstroCloudflare工程实践

这个个人网站终于上线了。它承载四件事:我是谁(关于我)、我做过什么(项目展示)、我在想什么(博客)、我在学什么(课程笔记)。这篇文章记录建站过程中的几个关键决策。

为什么是静态站

对个人网站来说,动态后端往往是个负担而不是资产:数据库要备份、服务要监控、更新要发布。而我的内容本身就是最好的代码——文章是 Markdown,项目描述是 TypeScript 数据,课程笔记是自动追加的学习记录。

静态优先意味着:

  • 内容即代码:全站内容进 Git,每一次修改都有历史、可回滚、可审计;
  • 零运维负担:没有服务器要维护,Cloudflare 的 CDN 天然扛流量;
  • :没有运行时渲染,访问者拿到的就是最终 HTML。

为什么是 Astro 7

Astro 的「岛屿架构」对内容型站点是天然契合:页面默认零 JavaScript,只有需要交互的地方(比如主题切换按钮)才写一点点脚本。

这个版本用到了几个关键能力:

  • 内容集合(Content Collections):博客和课程笔记用 Markdown + Zod schema 管理,类型安全,写错了字段构建直接报错;
  • 项目展示用 TypeScript 数据文件:12 个项目是结构化短数据,用 src/data/projects.ts 比 Markdown 更合适——类型检查、排序可控、详情页直接由 getStaticPaths 生成;
  • Tailwind CSS 4:通过 @tailwindcss/vite 插件接入,CSS-first 配置,没有 tailwind.config.js

深色/浅色主题切换是这里唯一的前端交互:首帧渲染前用一段内联脚本读取 localStorage 决定主题,避免「先白后黑」的闪烁。

最有意思的部分:课程笔记流水线

我的课程笔记有一个特殊约束:12 门课的 学习记录.md 不在网站仓库里,而是由我的自动化学习任务每周持续追加

设计上我把它做成一条单向流水线:

D:\Project\课程\{课程}\学习记录.md   (源头,自动化任务只写这里)
        │  scripts/sync-notes.mjs(白名单只认「学习记录.md」)

src/content/notes/{slug}.md        (生成物,提交进 Git)
        │  Astro 内容集合

/notes 列表页 + 每门课详情页

几个关键设计:

  • 白名单复制:只复制 学习记录.md 一个文件名,跳过 .workbuddy/课程资料/ 这类目录——源头目录里的隐私文件永远不会进入网站;
  • 幂等写入:生成内容与磁盘一致就跳过,避免每次构建都产生 Git diff;
  • 挂进 npm 生命周期predev / prebuild 自动执行同步,不需要记得手动跑。

「自动化任务只管追加、网站只管渲染」——两边各司其职,互不打扰。

部署

部署用 Cloudflare Pages,一条命令搞定:

npm run deploy   # = 同步笔记 → astro build → wrangler pages deploy

目前用的是免费子域名,以后有自己的域名了,绑定也只是一个配置项的事。

下一步

留言板在计划中,但我更倾向于用 Cloudflare 生态内的方案(Workers + D1 或 Giscus),而不是为一个小功能再引入一套 Supabase 依赖。以及——继续把学习记录写下去,让 /notes 真正长起来。

这个网站的源代码、更新历史、每一篇文章,都完整记录在 Git 里。这也是我建站的初衷:让时间沉淀下来的东西,有一个公开、可信、可持续的容器。