文章 PIN

Developer notes / Archive

从 0 到上线:我的个人博客技术选型

从写作需求出发,拆解 Markdown 内容、Astro 构建、局部交互与外部数据降级,选择一套能长期维护的个人博客架构。

2026/08/05 10 min read 0 浏览
#Astro#TypeScript#静态站点#部署
猫耳看板娘在海边工作台搭建个人技术博客
目录 / On this page

这个博客既是作品集,也是开发日志。我希望它能长期记录项目、设计判断和踩坑过程,但不想为了写一篇文章再维护一套后台、数据库和服务器程序。

所以这次选型的重点不是“堆一个完整博客系统”,而是找到一条足够短、可追溯、随时能迁移的发布路径:从一份 Markdown 开始,到浏览器里的一篇静态文章结束。

目标很简单:内容属于我,发布过程可重复,外部服务失效时文章仍然能打开。

目标与约束

开始写代码前,我先写下几条不能妥协的条件:

  1. 文章必须以 Markdown 存在仓库里,Git 就是历史记录和备份;
  2. 首页除了文章,还要能展示项目与少量动态状态;
  3. 正文页以阅读为中心,不能被首页的视觉元素打扰;
  4. 不需要用户账号、评论写入或实时协作,就不引入数据库;
  5. 静态内容不能依赖 GitHub、Steam 等外部接口实时返回;
  6. 以后无论迁移域名、托管平台还是重做界面,文章链接都应保持稳定。

这也意味着,一些成熟但更重的方案暂时不合适。完整 CMS 的后台体验很好,但同时带来了账号、升级、备份和运行环境;单页应用加 API 能做更复杂的交互,却为一个个人博客引入了持续运行的服务。

架构概览

下面是本站实际采用的数据流。核心内容在构建时进入静态页面;GitHub 和 Steam 只负责补充首页状态,并且有本地回退数据。

个人博客构建与数据流架构图

这张图里最重要的不是组件名称,而是两条边界:

  • 文章与项目可以独立构建,不依赖外部网络;
  • 外部数据只能增强体验,不能决定站点是否可用。

内容从哪里来

文章和项目都以 Markdown 保存在 src/content/ 中。每篇内容都有独立的 frontmatter:标题、摘要、日期、标签、阅读时长和发布状态。Astro 的 Content Collections 会在构建前校验这些字段,把“漏写摘要”或“日期格式不对”这类问题提前暴露出来。

这样做带来了三个很实际的好处:

  • 写作工具不被锁定:本地编辑器、GitHub 网页、任意支持 Markdown 的工具都可以用;
  • 内容天然有版本记录:每次修改都能追溯,也能随时恢复;
  • 迁移成本低:内容是普通文件,不依赖某个 CMS 的私有数据库结构。

对个人博客来说,Git 不只是部署触发器,更像是最简单可靠的内容库。

为什么选 Astro,而不是全站客户端渲染

博客的主体是文章、项目描述和归档列表,它们在用户打开页面前就应该准备好。Astro 的默认静态输出很适合这种场景:构建时读取内容,生成每篇文章的 HTML、目录和 SEO 信息,访问者拿到的是已经完成的页面。

但“静态”不等于完全没有交互。这个站点仍然保留了主题切换、系统时钟、音乐控制、文章目录高亮和看板娘等体验。处理方式是把真正需要浏览器状态的部分做成 Vue islands,其余内容继续保持静态。

这条边界很重要:

  • 文章阅读不需要等待客户端框架启动;
  • 交互组件可以独立演进,不会牵动文章路由;
  • 页面不会因为一个小按钮而变成整站 JavaScript 应用。

外部数据如何不拖垮首页

首页会读取 GitHub 公开项目和 Steam 状态,但我不让页面组件直接使用接口的原始结果。数据先经过 src/data/external.ts 映射为站点自己的类型,再交给项目卡片和状态卡片渲染。

如果网络超时、接口限流或字段变化,就回退到 src/data/homepage.ts 中的静态快照。这样即使第三方服务临时不可用,文章、导航和项目展示也不会消失。

这是我在个人项目里很看重的一条原则:外部 API 是可替换的输入,不是页面可用性的前提。

构建与发布:先把流程做短

当前发布链路很短:写 Markdown、提交 Git、构建静态文件,然后发布到静态托管。

pnpm build 会生成完整的 dist 目录,其中包括文章页、归档页、项目页、RSS、站点地图和所需资源。静态托管只需要提供这些文件,不需要运行 Node 服务,也不需要让访问请求穿过数据库。

如果后续部署到国内自建服务器,最后一步可以由 Nginx 承担;如果选择托管平台,则把同一个 dist 目录交给平台即可。无论部署在哪里,内容结构和构建结果都保持一致。

我刻意没有加入的东西

有些能力现在看起来“完整”,但会把维护成本推高,所以第一阶段没有加入:

  • 自建评论和登录系统;
  • 基于数据库的实时阅读统计;
  • 在线富文本编辑器;
  • 为追求实时性而常驻运行的后端服务;
  • 把 GitHub 或 Steam 接口当作首页必需依赖。

这些不是永远不做,而是等需求真的出现再做。比如评论量足够多时再考虑评论服务;有稳定访问量时再增加隐私友好的统计;外部状态确实需要分钟级更新时,再设计单独的缓存和刷新机制。

这套方案的代价

静态方案也有边界。每次文章发布都需要重新构建;文章数量很大时构建会变慢;实时互动功能需要额外服务。它不是“什么都能做”的架构,而是针对当前问题的架构。

不过对一个正在积累作品和写作习惯的个人站点来说,这种取舍是值得的:我把复杂度留给真正需要它的时候,把时间优先花在内容和项目上。

下一步

这篇文章之后,我会继续补两类内容:一类是 pomelo-chatSenrenTalk 这样的项目复盘,讲清楚问题、实现和取舍;另一类是博客本身的维护记录,例如外部数据刷新、部署、性能和响应式调整。

博客的价值不在于用了多少工具,而在于它能否持续把开发过程变成可阅读、可复用的经验。

参考与延伸阅读

Now Playing

Every Day Is NightGaroad

0:00 / 0:00

播放列表 · 4 首