余白

关于代码、工具,以及那些不值得单独写进文档的事。

静态博客为什么用 Astro

技术技术Astro

博客是个被过度工程化的品类。搜「如何搭博客」,出来的方案往往带着数据库、后台、评论系统、图片处理服务,最后为了写一篇八百字的随笔,得先维护五个容器。

实际情况是:一个博客的构建期只需要做三件事。

  1. 把 Markdown 变成 HTML;
  2. 生成文章列表和标签页;
  3. 输出一个 RSS。

这三件事都在构建时完成,运行时不需要任何逻辑。所以博客天然适合静态站,剩下的问题只是「用哪个工具生成」。

选 Astro 的理由

同类工具里,Hugo 构建最快,但模板语法要另学一套;Next.js 能做,但为了三件事拉进整个 React 运行时;纯手写 HTML 最自由,代价是每加一篇文章都要复制粘贴一遍页面结构。

Astro 的位置刚好在中间:页面仍然是 .astro 文件,写法接近 HTML 加一点 JSX 的前置脚本,而文章列表、标签页这类「每个站点都要写一遍」的东西,可以完全靠数据驱动生成。

例如标签页,全部逻辑就是扫一遍文章的前置字段:

// src/pages/tags/[tag].astro
export async function getStaticPaths() {
  const posts = await getPosts();
  const tags = new Set<string>();
  for (const post of posts) {
    for (const tag of post.data.tags) tags.add(tag);
  }

  return [...tags].map((tag) => ({
    params: { tag },
    props: { tag, posts: posts.filter((p) => p.data.tags.includes(tag)) },
  }));
}

新增一个标签,不需要改任何页面代码,也不需要注册路由。

文章就是文件

内容用 Markdown 存放在 src/content/posts/,前置字段只有四个:

字段 作用
title 标题
date 排序依据,同时决定文章归到哪一年
summary 列表页摘要与 <meta name="description">
tags 标签页与 RSS 分类

写完一个 .md 文件,列表、标签、RSS、站点地图会一起更新。没有任何一步需要在网页后台点「发布」。

顺手拿到的两件事

类型检查。 前置字段用 Zod 定义,tags 写成字符串、date 写成非法日期,构建会直接失败——比线上发现某篇文章的日期是 2026-13-01 要好。

没有客户端 JavaScript。 默认输出纯 HTML 和 CSS,页面里没有一行脚本。移动端的首屏因此几乎不受网络状况影响。

代价也很明确:没有评论(本来也不需要)、没有全文搜索(文章少于一百篇时用不上)、没有后台编辑(编辑器就是 VS Code)。这三样对个人博客都不是缺点。