知识库

Astro Content Layer 用 schema 强制「蒸馏」

glob loader + Zod schema 让内容成为带强约束的数据;写不出 summary 的笔记直接构建失败,把价值观写进了类型。

为什么把 summary 设成必填

内容组织层的核心决定是:把 Markdown 当成带强类型的数据,而不是自由文本

content.config.ts 里用 Zod 定义 schema,summaryunknownsquestions 三个字段都不是可选的。这不是为了好看,而是一道闸门——如果我没法用一句话 总结这次对话学到了什么,那这篇笔记本身就没有沉淀价值,不该进库。schema 校验 会在 astro build 阶段直接失败,逼我在写笔记时就完成提炼。

边界条件

  • loader 是构建期执行glob({ base: './content/garden' })base 相对项目根目录解析,所以内容目录能放在 src/ 外面,让 Obsidian 直接 打开整个 content/ vault。
  • 配置文件位置固定:内容集合的定义必须在 src/content.config.ts, 这一点和内容目录的自由位置是两回事,别搞混。
  • 校验即文档z.enum(['claude','cursor','manual','other']) 既约束了 取值,也顺手记录了「这条知识从哪来」。

最小示例

const garden = defineCollection({
  loader: glob({ pattern: "**/*.{md,mdx}", base: "./content/garden" }),
  schema: z.object({
    summary: z.string().max(120), // 写不出就构建失败
    // ...
  }),
});

记住一件事:schema 是价值观的落点。想改变自己产出内容的方式,先改 schema。

🔍 此前不知道自己不知道的

  • ·Content Layer 的 loader 是构建期执行的,`base` 路径相对项目根目录而非 config 文件
  • ·Astro 7 的 content 配置文件必须放在 `src/content.config.ts`,而内容目录可以在仓库任意位置
  • ·`z.string().max(120)` 这类校验失败会直接中断 `astro build`,而不是运行时报错

❓ 下次值得追问

  • ·Live Content Collections(v6+)能否让 Obsidian 编辑时热更新而不重启 dev server?
  • ·大量笔记时 glob loader 的增量构建表现如何,要不要换成数据库 loader?

🔗 关联笔记