← Writing

从零构建一个极简的静态博客系统

不依赖框架,再到 Astro 的渐进迁移

很多人以为,搭一个博客需要 React、需要 Next.js、需要 CMS、需要花一周时间研究最佳实践。

其实不需要。

第一阶段:纯 HTML

我最初的”墨笺”,只有四个 HTML 文件:index.htmlblog.htmlpost.htmlabout.html

加上一个 style.css 和一个 main.js

就这些。 写完上传到任意静态托管,三分钟搞定。

真正的问题从来不是”工具够不够”,而是”我有没有内容”。

第二阶段:写文章变得痛苦

第十篇文章的时候,我意识到 HTML 写文章太痛苦了——每一篇都要复制 post.html,改标题、改日期、改正文、改 meta 标签。

重复,是引入工具的最好理由

于是开始寻找方案。

三个候选

Hexo / Hugo

成熟、生态大。但模板系统有自己的语法,迁移起来要重写所有页面。

Next.js / Nuxt

太重。我只是写文章,不需要服务端、不需要数据库、不需要 SSR。

Astro

刚好。它的内容集合(Content Collections)让 markdown 成为一等公民,schema 由 zod 校验;它默认零 JS 输出,需要时再 island 化;最重要的——它对静态托管极度友好

第三阶段:迁移到 Astro

迁移做的事情,其实非常少:

  1. 把 4 个 .html 改写成 .astro,复用一个 BaseLayout
  2. 把文章正文从 HTML 提取成 .md,配上 frontmatter
  3. 写一个 [slug].astro 动态路由
  4. 把原来的 style.css 整段拷进 src/styles/legacy.css 不动

就这些。

几个有意思的取舍

1. 不用 Tailwind

原项目已经有完整的 CSS 设计令牌系统,再叠一层 Tailwind 反而是负担。不重写就是最大的 KISS。

2. 不用 SSR

Astro 默认 output: 'static'。所有页面都是 npm run build 时生成的纯 HTML。OG 图、RSS、sitemap,都在 build 阶段一次性吐出来。

3. 搜索用 Pagefind

Pagefind 在 build 之后扫描 dist/,生成一份索引。前端运行时按需加载,零服务端。

4. 评论用 Giscus

把评论交给 GitHub Discussions 处理。零运维成本。

一个更核心的事

工具能解决的问题,永远只有一种:减少摩擦

减少了写文章的摩擦——所以我会写得更频繁。

减少了发布的摩擦——所以我会发布得更及时。

减少了维护的摩擦——所以我能把精力留给真正要紧的事:写出值得读的字

如果一个工具的复杂度大于它带来的便利,那它就不是合适的工具。

KISS 与 YAGNI 不是简陋,是克制