ryu.com ← 返回日志
三个周末,我给博客写了个静态生成器 题图
代码

三个周末,我给博客写了个静态生成器

2026 年 7 月 11 日 · 约 13 分钟阅读

事情是这样的:我的博客需要重建。GCP 封号之后,我决定不再依赖任何后端。但直接手写 HTML 维护几十篇文章显然不现实。我需要一个工具。

现有的选择都太重了——Hugo、Jekyll、Astro、Next.js。它们是好工具,但我不想为一个博客引入 200MB 的 node_modules。我只需要三件事:把 Markdown 转成 HTML、套一个模板、生成 RSS。

所以我在三个周末里,写了一个不到 200 行的 Node 脚本。

第一个周末:想清楚「不做什么」

大部分工具的问题不是功能太少,而是太多。我花了第一个周末列「不需要」清单:

这个「减法」过程比写代码更重要。它让我想清楚一个博客到底需要什么:内容 + 排版 + 链接。其他都是噪音。

第二个周末:写代码

核心逻辑很简单:

const fs = require('fs');
const path = require('path');
const { marked } = require('marked');

// 读取所有 Markdown 文件
const posts = fs.readdirSync('content')
  .filter(f => f.endsWith('.md'))
  .map(f => parsePost(f))
  .sort((a, b) => b.date - a.date);

// 生成每篇文章的 HTML
for (const post of posts) {
  const html = applyTemplate(post);
  fs.writeFileSync(`dist/${post.slug}.html`, html);
}

// 生成首页
const indexHTML = applyIndexTemplate(posts);
fs.writeFileSync('dist/index.html', indexHTML);

// 生成 RSS
const rss = generateRSS(posts);
fs.writeFileSync('dist/rss.xml', rss);

实际代码比这个多一点——处理了 frontmatter、URL 规范化、相对路径、代码高亮。但核心思路就是这三步:读取、转换、输出。

第三个周末:删掉重写

第二个周末写完之后,我试着导入了 20 篇旧文。出现了几个问题:

第三个周末,我把整个脚本删了,重写。这次更简单——放弃了 Markdown 自动转换,直接手写 HTML。听起来是一种倒退,但实际上:

最终这个「静态生成器」退化成了一个 50 行的脚本,它做的唯一一件事就是:扫描 posts/ 目录下的 HTML 文件,提取标题和日期,生成首页的列表。

Less is actually more

这个经历让我重新思考「工具」的意义。最好的工具不是功能最多的那个,而是刚好够用的那个。对于个人博客来说,一个文本编辑器和一个 HTML 文件,就是最好的 CMS。

如果你也想写博客,我的建议是:先写,再考虑工具。先把内容写出来,放在一个 HTML 文件里,上传到任何一个能托管静态文件的地方。当你发现手动维护变得痛苦的时候,再考虑自动化。但大多数情况下,手动维护的痛苦远小于学习一个复杂框架的痛苦。


这个站的源码可以在 GitHub 上找到。没有构建步骤,clone 下来直接就能跑。

继续阅读