
AI帮我造博客(四):后端选型——内容从哪里来?

📖 本文是「AI帮我造博客」系列第四篇。上一篇:AI帮我造博客(三):博客架构入门——前后端分离是什么意思?
TL;DR
内容管理是博客的核心。作为一个“既要又要”的程序员,我想要 Markdown 的写作自由,又想要 CMS 的管理便利。在考察了 Strapi、Payload 和 Directus 后,我最终选择了 Strapi。
不是因为它技术最先进,而是因为它的社区最大,遇到坑最容易搜到答案——对于在这个项目上“不想造后端轮子”的我来说,这就是最优解。
内容的家在哪里?
在搞定架构设计(前后端分离)之后,摆在面前的是一个非常具体的问题:我写的文章,到底该存在哪?
最简单的方案当然是 Git + Markdown。像 Hexo 或 Hugo 那样,把文章作为 .md 文件放在仓库里,编译时读取。这是程序员最舒心的方案:版本控制、本地编辑器、离线写作,一切都尽在掌握。
但我的目标不仅是一个静态博客,而是一个内容系统。
试想一下通过单纯的文件来管理几百篇文章的痛苦:
- 改标签:如果要把 "AI" 这个标签改成 "Artificial Intelligence",我得用脚本遍历几十个文件去替换文本。
- 搞推荐:如果想在文章底部加一个“相关阅读”,只靠文件系统几乎没法做,除非每次编译都把所有文章读一遍来计算相关性。
- 做互动:文件是静态的,存不了读者的评论、点赞。
所以我需要一个 Headless CMS(无头内容管理系统)。
如果不理解“无头”是什么意思,可以把它想象成一个只有后厨的餐厅:它只负责把菜(内容数据)做好切好,通过窗口(API)递出来。至于这盘菜是端到豪华包间(Web端)、打包带走(App端)还是给机器人吃(AI训练),它完全不管。它只负责存数据、提供接口。
选型战场:Headless CMS 的“三国杀”
在 AI 的辅助调研下,我把目光锁定在了三个主流选手身上。这一过程就像是在选车:
1. Payload CMS:程序员的梦中情车
Payload 是那个让我最纠结的“白月光”,也是目前 Next.js 生态里最火的新星。
它的核心哲学是 Code-First(代码即结构)。
在传统的 CMS 里,你通常需要登录后台,点击“创建模型”,输入“文章”,增加“标题”字段……这一顿鼠标点点点之后,系统才把你的数据结构保存在数据库里。
而在 Payload 里,你是在写代码。你定义一个 Article.ts 配置文件,写上 fields: [{ name: 'title', type: 'text' }],保存代码,后台界面就自动生成了,数据库表也建好了。这就像是用代码“画”出了后台。
为什么它是“白月光”?
- 版本控制友好:所有的数据结构变化都在代码里,Git 提交记录清清楚楚。
- 开发体验无敌:因为它本身就是 TypeScript(一种自带类型“拼写检查”的升级版 JavaScript)写的,你在后端定义的字段,在前端调用时自动就有类型提示。再也不用担心“我那个字段到底是叫
img还是image”这种低级错误。 - 极度灵活:它不像一个外挂的系统,更像是一个你可以随心所欲定制的 npm 包。
这就好比:你自己组装的一辆高性能赛车。没有多余的内饰,但引擎、悬挂、变速箱的每一个参数都由你精准控制,开起来人车合一。
2. Directus:极致性能的瑞士军刀
Directus 走的是另一条极端路线:Database Mirroring(数据库镜像)。
大多数 CMS 会在数据库之上封装一层厚厚的逻辑,把你和数据库隔离开。但 Directus 不一样,它就像是一个给数据库套上的皮肤。
你给它一个现有的 Postgres 或 MySQL 数据库,它会瞬间分析你的表结构,然后立刻生成一套漂亮的 API 接口和一个功能完备的管理后台。你不需要迁移数据,也不需要为了迁就 CMS 而修改表结构。
它的杀手锏:
- 即时 API (Instant API):连上一张表,API 马上就通了。
- 无依赖:如果你哪天不想用 Directus 了,直接把它删了,你的数据库干干净净,没有任何 CMS 留下的垃圾字段。
- 性能怪兽:因为中间层极薄,加上 Node.js 的底层优化,它的响应速度通常是毫秒级的。
这就好比:一把精密的瑞士军刀。冷峻、高效、多功能。它不试图教你如何管理内容,它不仅给你提供了最锋利的工具,还允许你直接操作最底层的素材。
3. Strapi:略显臃肿的老大哥
最后是 Strapi,市场占有率第一的老大哥。
说实话,它的技术架构在今天看来稍微有点“油腻”。
它启动慢,空跑内存就要占用几百兆;它的后台虽然功能全,但加载起来总有一种钝感。而且它的版本升级(特别是 v4 到 v5)经常因破坏性变更让开发者叫苦连天。
但它赢在“平庸的全面”。
它不需要你懂 TypeScript(Payload 门槛),也不需要你懂数据库设计(Directus 门槛)。它提供了一个可视化的 Content-Type Builder,就像搭积木一样,拖个文本框、拖个图片上传区,后台就搭好了。它是最接近传统 WordPress 使用体验的 Headless CMS。
这就好比:一辆传统的燃油 SUV。
它费油、起步肉、车机系统也不智能。但它皮实、空间大、配件便宜,不管开到哪个修车店,师傅都会修。对于不想折腾的人来说,这就叫“靠谱”。
📊 横向对比表
| 维度 | Strapi | Payload | Directus |
|---|---|---|---|
| 一句话定位 | 社区最强、生态最丰富 | TypeScript 开发者首选 | 数据库包装器、极致性能 |
| 开发模式 | GUI (界面拖拽) | Code-first (写代码) | GUI (直接映射数据库) |
| GitHub Stars | ~70k | ~40k | ~34k |
| 管理界面 | React | React | Vue.js |
| API 响应 | 120-150 ms | 80-100 ms | 33 ms |
| 推荐配置 | 4核/8GB | 2核/4GB | 1核/1GB |
| TS 支持 | ⭐⭐⭐ (能用) | ⭐⭐⭐⭐⭐ (完美) | ⭐⭐⭐⭐ (不错) |
| 学习曲线 | 简单 | 陡峭 (需熟练 TS) | 中等 (需懂 SQL) |
还有谁?其他值得一看的选手
除了这三位主角,市面上还有几个不得不提的老面孔,简单说下我为什么没选它们:
WordPress (Headless 模式)
老牌王者。虽然它也能当 Headless 用,但它的内核依然是 PHP。作为一个想全栈 JavaScript 的人,我不想在服务器上再装个 PHP 环境,也不想去维护那个庞大的插件库。
Ghost
专注于博客的优雅选手。界面极美,写作体验极佳。但它太"博客"了。如果我只想写写文章,选它准没错。但我想做一个更通用的内容系统(Content System),Ghost 的扩展性稍微差点意思。
Sanity / Contentful
SaaS 领域的贵族。它们不提供自托管版本(或者很难搞),数据存别人家。对于要把一切抓在手里的"数据控制狂"(我)来说,不能自托管(Self-hosted)就是一票否决。
为什么我不争气地选了 Strapi?
这其实是我内心最大的挣扎。
作为一个有追求的工程师,我本能地更喜欢 Payload。
Payload 的 Code-first 模式太优雅了。所有配置都在代码里,可以进 Git 版本控制。而在 Strapi 里,你在后台拖拽生成的 Schema(数据模型)是以 JSON 文件存在的,虽然也能进 Git,但总感觉是在操作一个黑盒。而且,Payload 原生支持 TypeScript,对于我有着巨大的吸引力。
但我最终还是选择了 Strapi,理由非常现实,甚至有点“俗”:
1. 出了 Bug 能搜到答案 (生态成熟度)
Strapi 的 GitHub Stars 数是其他两家的总和还多。这意味着我遇到的任何一个报错,Google 一下,StackOverflow 以前肯定有人问过。
Payload 当时(2025年初)社区相对还比较嫩,很多时候遇到问题得去 Discord 翻记录或者读源码。对于一个“不想在后端耗费太多精力”的人来说,Strapi 这种“满大街都是修车店”的安全感太重要了。
2. 可视化建模的“傻瓜”优势
虽然 Payload 的代码定义很帅,但 Strapi 的 Content-Type Builder(可视化拖拽建表)对于新手真的太友好了。
有时候我只是想加个“置顶”字段,或者给文章加个“标签”关系,Strapi 里点两下鼠标就完了。不需要切代码、不需要重新编译、不需要管 TS 类型定义。这种“所见即所得”,在项目初期极大地降低了心智负担。
3. 插件如海
Strapi 拥有最庞大的插件市场。SEO 插件、Sitemap 生成、图片格式转换……基本上一搜都有。
我想做个 SEO 优化,Strapi 里直接装个官方 SEO 插件,填填空就好了。而在 Payload 里,当时我可能得自己写 Hook 来注入 meta 标签。对于想快速上线的我来说,不想重复造轮子。
如果你是初级个人开发者,或者团队里有非技术人员需要管理内容,Strapi 依然是目前最推荐的“大众选择”。 它不够完美,但它足够稳。
这一路踩过的坑
既然是真实记录,就不能只报喜不报忧。虽然选了 Strapi,但这几个坑是实实在在的:
1. 资源占用是硬伤
Node.js 应用的内存管理一直是个谜。Strapi 跑起来后,如果是小内存服务器(比如 1核2G),经常会因为内存不足而崩溃(OOM - Out Of Memory)。后来我不得不在服务器上加了 Swap(虚拟内存,把一部分硬盘当内存用)才稳住它。
2. 到底是 CMS 还是数据库?
Strapi 默认把所有数据都存数据库,包括我精心排版的文章内容。这就带来了一个分裂感:我在本地写 Markdown 很爽,复制进 Strapi 的富文本编辑器里,体验就降级了。
这也导致了我后来做了一个非常复杂的同步脚本(这是后话),强行让“本地 Markdown”和“远程 Strapi”共存,用 Strapi 做数据管理,用本地文件做写作源。这算是一种对 Strapi 编辑体验不佳的妥协。
3. 富文本的烦恼
Strapi 的富文本字段输出的是 Markdown 格式,但前端渲染时又是另一回事。图片怎么处理?站内链接怎么跳转?代码高亮怎么做?这些都需要在前端通过 react-markdown 等库再次解析。并不是“存进去什么样,拿出来就什么样”。
⚠️ 剧透预警:
这篇文章真实记录了项目初期的决策过程。软件工程没有银弹,只有当下的取舍。
在几个月后,随着我对内容控制力的需求进一步提升(通过 Python 重写了整套同步系统),Strapi 那个引以为傲的可视化后台对我来说变得有些累赘。
但这并不妨碍 Strapi 在现阶段是我的最佳选择。它就像是新手村里那把最顺手的铁剑,虽然未来我非常可能会换上更轻盈的光剑(Payload),但如果没有这把铁剑,我可能连村口都出不去。
如果让我现在重新选,在完全具备了驾驭复杂系统的能力后,我可能会转向 Payload。但这正是成长的乐趣,不是吗?
总结
后端选型,本质上是在选数据流动的起点。
我放弃了极致的性能(Directus)和极致的开发体验(Payload),选择了一个最稳妥、资料最多、虽然有点笨重但足够成熟的方案——Strapi。
因为它让我的数据有了家,也让我能腾出手来,去处理更重要的部分:这个博客到底长什么样?
这就是下一篇的主题:前端选型——为什么是 Next.js?
📚 AI帮我造博客系列导航
上一篇:AI帮我造博客(三):博客架构入门——前后端分离是什么意思?
下一篇:AI帮我造博客(五):前端选型——为什么是 Next.js?
