从 Obsidian 到博客的发布流程

/ 4 min read

文章只在 Obsidian 里写一份,公开什么、什么时候公开,由一个 status 字段和一条命令决定。

这个博客的文章都写在 Obsidian 里。我不想为了发布再维护第二份稿子,也不想把整个笔记库公开,所以在笔记库和网站之间加了一道很薄的导出步骤。这篇文章记录它是怎么工作的。

整体思路

原稿留在 Obsidian,博客项目通过一个软链接读取博客目录,把允许公开的文章导出成一份干净的副本,网站只读这份副本:

Obsidian 博客目录
    ↓ content 软链接(只在本机存在)
校验 metadata,筛选 status: published
    ↓
published/posts/{slug}.md  +  published/assets/
    ↓
Astro 构建 → GitHub → Vercel

为什么要多一份副本

部署平台访问不到我电脑上的笔记库。把导出结果提交进仓库,网站就能在任何地方独立构建。

用 status 决定公开范围

每篇文章的 frontmatter 里有一个 status 字段:

状态 发布时的行为
draft 不导出
published 导出文章和它引用的图片
withdrawn 移除已公开的副本

文件放在哪个目录、叫什么名字都不影响发布,程序只看这个字段。网址则由 slug 决定:

---
title: 从 Obsidian 到博客:一条命令的发布流程
slug: obsidian-to-blog
status: published
date: 2026-10-01
---

移动和改名不会改变网址

原稿路径用来组织笔记,slug 用来确定网址。只要 slug 不变,文章挪到别的目录或者改了标题,链接都不会失效。

Obsidian 语法怎么处理

Obsidian 的几种写法不是标准 Markdown,需要在导出时转换:

链接到未发布的文章会报错

如果一篇公开文章用双链指向了草稿,发布会直接停下并指出是哪个文件的哪一行,而不是悄悄把草稿也公开,或者留下一个坏链接。

一条命令

发布只需要执行:

npm run release

它依次做这几件事,任何一步失败都会停下,不会推送:

  1. 校验所有文章的 metadata、链接和图片。
  2. 把公开文章导出到临时目录,并用它完整构建一次网站。
  3. 构建通过后才更新 published/。
  4. 只提交 published/ 的变更并推送。

想先看看会发生什么,可以加上 --dry-run,它只做前两步。

小结

一句话

写作只在 Obsidian 里发生;公开什么由 status 决定;发布是一条可以反复执行的命令。