MDX、内容集合与作为架构的内容
为什么仅仅将 Markdown 文件拖入文件夹并不能构成一个发布系统,以及如何构建一个可扩展的发布系统。
目录
在 JavaScript 框架中采用 MDX 或 Markdown 时,最常见的失败模式是将其视为美化过的文字处理器。
团队配置一个解析器,将五十个 .mdx 文件拖入 /content 文件夹,然后认为他们有了一个发布系统。六个月后,他们得到了一堆没有类型约束的文章。Frontmatter 变得不一致。指南页面使用了与博客文章不同的布局,但仅仅是因为某位作者记得导入了正确的组件。重新组织文档需要对整个代码库进行正则表达式搜索。
当您的产品是阅读材料时,您的内容模型就是您的架构。
作为架构的内容的论点
在像 Interface Atlas 这样基于文件的出版物中,您必须停止将 src/content/ 文件夹视为存储桶。它是一个数据库。
既然它是一个数据库,它就需要一个模式(schema)。它需要关系。它需要约束。在 Astro 中,我们使用内容集合来强制执行这种架构。
作为发布系统的仓库
graph TD
subgraph 数据库层
C1[指南集合] -->|通过 Zod 验证| S1(指南模式)
C2[术语表集合] -->|通过 Zod 验证| S2(术语表模式)
end
subgraph 图谱层
S1 -->|topicKeys| T[主题中心]
S1 -->|glossaryKeys| C2
end
subgraph 表现层
T --> R1[Astro 主题路由]
C1 --> R2[Astro 指南路由]
C2 --> R3[Astro 术语表路由]
end
从 Markdown 走向内容集合
无类型堆砌(失败模式)
在内容集合出现之前,框架通过 glob 导入加载 markdown 文件。您会得到作者键入的任何 frontmatter。
如果作者输入了 diffculty: hard 而不是 difficulty: Advanced,构建将会通过,但页面会悄无声息地丢失难度徽章。内容逻辑变得隐藏在试图解析损坏数据的脆弱 UI 组件中。
强类型集合(解决方案)
Astro 的内容集合通过在内容和渲染之间引入严格的边界来解决这个问题。
// src/content.config.ts
import { defineCollection } from 'astro:content';
import { glob } from 'astro/loaders';
import { z } from 'astro/zod';
export const guides = defineCollection({
loader: glob({ pattern: "**/*.mdx", base: "./src/content/guides" }),
schema: z.object({
title: z.string(),
description: z.string(),
topicKeys: z.array(z.string()), // 强制执行图谱关系
difficulty: z.enum(["Foundation", "Intermediate", "Advanced"]), // 防止拼写错误
}),
});
这段代码教导了一个架构上的推论:内容错误现在是构建错误。 如果作者忘记了 topicKeys 数组,Astro 的构建将会失败。网站无法在损坏的状态下部署。
Frontmatter 是关系模式
一旦你有了强类型集合,Frontmatter 就不再仅仅是一个放标题的地方。它变成了构建你的内容图谱的关系模式。
在 Interface Atlas 中,我们不会在 MDX 文件的底部硬编码“相关指南”。我们使用 frontmatter 键:
---
title: "信息架构"
topicKeys: ["architecture", "seo"]
glossaryKeys: ["taxonomy"]
relatedGuideKeys: ["what-frontend-architecture-really-is"]
---
因为这是强类型的,路由层可以自动生成相关链接、主题中心标签和术语表工具提示。
基于 Git 的编辑工作流
当仓库就是 CMS 时,Git 工作流就是编辑工作流。
- 起草: 作者创建一个分支并编写一个 MDX 文件。
- 审查: Pull Request 变成了编辑审查。审阅者可以像评论代码一样评论散文。
- 验证: CI/CD 运行 Astro 构建。Schema 验证 frontmatter,MDX 验证组件语法。
- 发布: 合并到
main分支会触发到边缘节点的静态部署。
当团队试图强迫非技术编辑在没有像 Decap CMS 这样的工具的情况下直接使用 GitHub 时,或者当 MDX 文件被复杂的 JSX 严重污染以至于作者无法再阅读文本时,这个工作流就会失败。
当 MDX 不够用时
MDX 是一种混合媒介。它允许您将复杂的交互式组件直接嵌入到长篇文本中。但你必须知道何时停止。
如果一个 MDX 文件包含 40 行文字和 300 行复杂的 React 状态管理,你就越界了。内容现在屈从于应用程序逻辑。
规则: 保持 MDX 文件专注于阅读。如果一个交互式小部件需要复杂的本地状态,请将其抽象为一个 Island(群岛)组件,并从 MDX 文件向其传递简单的 props。
相关指南和术语
探索支持系统:
- 信息架构、内容架构与界面系统 — 内容结构如何驱动可发现性。
- 优秀技术指南的剖析 — 如何为该系统编写内容。
- 选择合适的技术栈 — 为什么 Astro 适合这种模型。