用 Obsidian 构建无感发布博客 — editorial cover photo

用 Obsidian 构建无感发布博客

从 Obsidian 写完笔记到博客自动上线,中间零摩擦。这套基于 Obsidian 加 Next.js 加 GitHub Actions 的发布管线,是怎么搭起来的,为什么要这么搭。

2026年3月28日·返回文章列表
文章大纲

写博客这件事,最大的敌人不是没东西写,是发布太麻烦。

我之前断断续续写过几个博客,最后都弃坑了,原因高度一致。写完一篇 Markdown,要手动搬到博客系统,要处理图片路径,要调格式,要点击发布。这套流程每多一步,坚持下去的概率就少一分。等「发布」变成一件需要专门腾出时间做的事,写作频率自然就降下来了。

这个博客系统就是为解决这个问题做的。核心理念一句话,写作和发布之间零摩擦。在 Obsidian 里写完笔记,把 frontmatter 的 publish 改成 true,剩下的全自动,几分钟后文章就上线了。这篇讲这套管线怎么搭的,以及每个选择背后的考量。

为什么写作端选 Obsidian

写作工具的选择,决定了整个工作流的体验。我选 Obsidian 有几个理由。

它是本地的。笔记存在本地文件系统,是普通的 Markdown 文件,不被任何平台锁定。这一点至关重要,因为博客系统要读这些文件来发布,本地文件意味着我可以完全掌控数据,想怎么处理就怎么处理。云端笔记工具(Notion、飞书)的数据锁在别人那里,要导出和自动化都不方便。

它支持双链和知识图谱。技术笔记之间关联很紧密,讲分布式锁要链到 CAP 定理,讲缓存要链到一致性。双链让这些关联自然建立,而且知识图谱能可视化整个笔记网络,发现自己没想到的连接。这是线性文档工具给不了的。

它的语法丰富。除了标准 Markdown,还支持 Wiki 链接 [note](/blog/note)、嵌入 > 📝 未找到笔记: note、Callout > [!type]、高亮 <mark>text</mark> 这些扩展。这些语法让笔记的表达力更强,但问题是它们不是标准 Markdown,博客系统要自己处理转换。

它有强大的插件生态。自动同步用 Git 插件,模板用 Templater,数据查询用 Dataview。这些插件把 Obsidian 从一个编辑器扩展成一个知识管理工作台。我的整个写作加发布流程,重度依赖其中几个。

发布管线的全貌

整个发布管线分五段,每段职责清晰。

写作在 Obsidian 里完成,产出的是带 Obsidian 特殊语法的 Markdown 文件。同步由 Obsidian Git 插件自动完成,每 5 分钟把 vault 里的改动 commit 加 push 到 GitHub 仓库。

构建由 GitHub Actions 触发。Actions 监听仓库的 push,一旦 vault/blog 目录有变化,就启动构建流程。构建做两件事,把 Obsidian 的特殊语法转成标准 Markdown(或者 MDX),然后用 Next.js 构建静态页面。

部署是构建的最后一步。构建产物通过 SSH 推送到服务器,替换旧的静态文件,重启服务。整个过程从写完笔记到文章上线,大概 3 到 5 分钟,全程不需要我干预。

Mermaid
正在渲染图表…

这套管线的精髓在于,每一段都是自动的,但每一段都是可独立替换的。写作端换 Typora 也行(只要产出 Markdown),同步换其他 Git 客户端也行,构建换其他静态站点生成器也行。Obsidian 不是绑定的,只是目前最顺手的。

语法转换,最关键也最坑的一环

Obsidian 的特殊语法(Wiki 链接、Callout、嵌入、高亮)不是标准 Markdown,Next.js 的 MDX 处理器不认识。所以中间需要一个转换层,把 Obsidian 语法转成 MDX 能理解的形式。

这个转换是整个管线里工程量最大的一块。我写了一个预处理模块,用正则加字符串处理,逐个语法转换。Wiki 链接 [note](/blog/note) 转成指向 /blog/slugified-note 的普通链接。Callout > [!type] 转成带样式的 HTML 块。嵌入 > 📝 未找到笔记: note 转成对目标笔记内容的递归引用。高亮 <mark>text</mark> 转成 <mark> 标签。

这块的坑在于边界情况特别多。Wiki 链接里有别名怎么办,嵌套的 Callout 怎么处理,代码块里的 [[ 不能被当成链接。每一个都要单独处理,处理不全就会在某些笔记上崩。

PlantUML 和 Mermaid 也要特殊处理。这两种图表语法在 Obsidian 里是代码块,转换层要把它们转成对应的渲染组件(远程图片或者客户端渲染)。这块踩过不少坑,比如 PlantUML 的编码、Mermaid 的客户端渲染失败兜底。

语法转换的设计原则

转换层要宽容,遇到不认识的语法不要崩,原样保留就好。笔记的内容是用户产的,各种奇怪的写法都会出现,转换层崩了等于整篇笔记都发不出去。我的做法是,每个语法转换都包在 try-catch 里,转不了的保留原文,至少让能转的部分正常显示。构建失败比渲染瑕疵严重得多。

发布控制,一个字段搞定

哪些笔记发布、哪些不发布,控制方式要简单。我用 frontmatter 里的 publish 字段。publish: true 就发布,不写或者 false 就不发布。

这个设计的好处是,控制粒度精确到单篇笔记,而且就在笔记自己的 frontmatter 里,不用额外维护一个发布清单。写完想发就加 publish: true,不想发就不加,想下线就改回 false

还有一些自动规则。某些目录(比如草稿、私人笔记)默认不发布,除非显式标记。笔记内容太短(少于一定字数)也不发布,避免把半成品发出去。这些规则在构建时的过滤逻辑里实现。

一些踩过的坑

图片路径是个经典坑。Obsidian 里图片引用用的是相对路径或者 vault 内路径,但博客上线后图片要在 public 目录下。我的处理是,构建时把 vault 里的图片资源拷到 public 目录,同时把笔记里的图片路径重写成上线后的路径。这块要处理好同名冲突和路径映射。

Frontmatter 的字段也要对齐。Obsidian 笔记的 frontmatter 字段(title、date、tags、description)要和博客系统期望的对上。日期格式要能被解析,slug 为空时从文件名生成。这些边界处理好,写作端就不用关心博客系统的细节,只管按 Obsidian 的习惯写。

增量构建。笔记多了之后全量构建会慢,理想是只构建变化的笔记。这块用 Next.js 的增量静态再生或者构建缓存来实现,能大幅缩短构建时间。目前我的笔记量还没到需要优化的程度,但这是未来的一个改进点。

这套工作流带给我的

用了这套管线之后,最直接的变化是写作频率上来了。因为发布不再是阻力,写完就发,发完就在线上,这个正反馈让人更愿意写。

更深的变化是,博客和笔记统一了。以前笔记是笔记、博客是博客,两边维护很累。现在笔记就是博客的源,写笔记等于在写博客,只是哪些发哪些不发的一个字段差别。知识沉淀和分享成了一个连续的过程,不是两件事。

这套「无感发布」的工作流,核心不是某个技术多炫,是把写作到发布之间的每一步摩擦都尽量消除。工具和自动化是手段,目的是让你能坚持产出。能坚持产出,这套系统就值了。技术人最大的浪费,是脑子里想了很多、手上记了一些,但因为发布麻烦最后没沉淀下来。这套管线就是为了让沉淀这件事变得毫不费力。

Continue Reading

关联文档推荐

查看全部
Obsidian 使用技巧 — editorial cover photo
作者:archy.shawn
声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。