AI 参与说明(Agent:Codex):本文根据 MDX、Astro、Obsidian 官方资料及社区插件作者文档辅助撰写与校验,资料整理于 2026-09-08。工具选择与内容组织建议是本文的工程判断;插件能力依据其公开说明,未进行 Obsidian 插件安装实测。运行记录:模型
gpt-6-astra,reasoning effortultra,执行入口 Codex Desktop,提供方openai,CLI 版本0.153.4(不代表桌面 App 版本)。
文章需要直接调用组件、根据数据生成内容时,MDX 很有价值;以文字、图片和普通代码示例为主时,Markdown 仍然足够。 Astro 提供正式的 MDX 集成,Obsidian 则主要依赖社区插件补充编辑和预览能力。选择格式时,需要同时考虑发布系统与日常写作工具。
先认识下面几个词。中文名称用于导读,后文保留对应的英文名称。
| 英文术语 | 中文名称 | 简要解释 |
|---|---|---|
| MDX | MDX | 可以在 Markdown 正文中使用组件和 JavaScript 的内容格式 |
| JSX | JavaScript 语法扩展 | 用类似 HTML 的标签描述界面,例如 <Notice /> |
| JavaScript expressions | JavaScript 表达式 | 会产生一个值的代码,例如 price * count |
| ESM | ECMAScript 模块 | 用 import 和 export 组织、共享代码与数据的模块机制 |
| props | 组件属性 | 调用组件时传入的数据,例如提示框的标题 |
| hydration | 水合 | 为服务端已生成的界面接上浏览器中的组件逻辑与状态 |
| frontmatter | 前置元数据 | 写在正文前的标题、日期等信息,常用 YAML 表示 |
| CommonMark | CommonMark | 对 Markdown 基础语法的明确规范 |
| GFM | GitHub 风格 Markdown | 在基础 Markdown 上补充表格、任务列表等语法的方言 |
MDX combines Markdown content with JSX, JavaScript expressions, and ESM. Its integration compiles the document into a JavaScript module that exports a component. 普通段落继续用 Markdown 写,需要特殊展示的地方再调用组件;整篇内容因此也能作为组件被其他页面引用。What is MDX? · Using MDX
MDX 比传统 Markdown 多了什么
这里的“传统 Markdown”指 CommonMark 一类正文语法。具体网站可能通过插件、模板或 HTML 获得更多能力,不能把某个渲染器的限制当成 Markdown 网站的共同限制。
| 能力 | Markdown 正文 | MDX 正文 |
|---|---|---|
| 标题、段落、列表、链接、图片、代码块 | 基础能力 | 继续支持常见写法 |
| 插入 HTML | 规范允许,具体平台可能过滤 | HTML 风格标签按 JSX 规则解析 |
| 调用项目组件 | 需要网站另行提供模板或扩展语法 | 可以直接写 <Notice title="提示" /> |
| 根据变量计算正文 | 不是 Markdown 自身的语义 | 可以写 {price * count} |
| 导入组件、共享数据、其他文档 | 不是 Markdown 自身的模块能力 | 可以用 import / export |
| 用数组生成重复内容、按条件展示 | 需要外部模板或程序处理 | 可以在表达式中使用 .map()、条件运算符等 |
| 把全文当作组件复用 | 需要网站额外封装 | 编译后的内容本身就是组件 |
例如,一组参数说明需要在十篇文档里保持一致,可以让十篇 MDX 调用同一个组件,并传入不同的 props。调整结构时修改组件即可。相应代价是这些文章开始依赖组件接口,组件重命名、参数变化或删除也会影响内容构建。这是由模块依赖关系带来的工程取舍。Using MDX:Components
交互不是文件扩展名自动带来的。 MDX 让交互组件进入文章成为自然的写法,但按钮状态、图表筛选和输入反馈仍由组件实现,浏览器执行方式由所用框架决定。MDX 也不只限于 React;支持哪些组件以及怎样运行,应看对应集成。MDX:How MDX works
这些常见能力并非 MDX 独有
GFM 表格、任务列表、代码高亮、数学公式和 Mermaid,并不是“用了 MDX 才能有”的功能。它们分别涉及 Markdown 方言、渲染插件或页面脚本,普通 Markdown 网站也可以提供。
MDX 核心默认不启用 GFM;YAML frontmatter 也需要插件或框架提供支持。Astro 的 MDX 集成会继承相应的 Markdown 配置,并提供 frontmatter 支持。因此要区分 MDX 格式能力与当前网站已经配置的能力。MDX:GFM · MDX:Frontmatter · Astro:Markdown content
已有 Markdown 文章能显示 Mermaid,不构成迁移 MDX 的理由;需要把一个可调参数的演示组件嵌入论述,才更能发挥 MDX 的作用。
先在浏览器中试一个完整示例
打开 MDX Playground,将以下内容放入编辑区,可以同时观察渲染结果与生成的 JavaScript。示例没有外部组件或依赖导入。
export const lesson = {
title: 'MDX Lab',
minutes: [10, 15, 20],
}
export function Badge({children}) {
return <strong style={{color: '#08745b'}}>{children}</strong>
}
# {lesson.title}
Total: {lesson.minutes.reduce((sum, value) => sum + value, 0)} minutes.
Status: <Badge>Ready</Badge>
<ul>
{lesson.minutes.map((minutes, index) => (
<li key={index}>Part {index + 1}: {minutes} minutes</li>
))}
</ul>
预期显示标题 MDX Lab、总时长 45 minutes、绿色的 Ready,以及三个分别为 10、15、20 分钟的列表项。把数组中的 20 改成 30,总时长会变成 55 minutes。
这里同时出现了三个新增能力:ESM 保存共享数据和组件定义;JavaScript expressions 计算总时长、生成列表;JSX 调用 Badge 并把 Ready 作为 children 传入。代码围栏中的 MDX 只展示源码,实际计算发生在 MDX 编译并运行之后。
写在同一文件里的 Badge 适合演示。正式项目可将组件移入工程,再在 MDX 中导入。复杂行为和样式集中到组件,正文便能继续围绕解释与例子展开。
MDX 怎样变成网页
下面以包含 client:visible 组件的 Astro 静态页面为例。构建先生成 HTML 和该组件所需的 JavaScript,浏览器先显示内容,等组件进入视口后再加载组件 JavaScript。普通静态内容不需要最后两步。
flowchart TD
A["MDX 正文<br/>与组件 import"] --> B["Astro 编译<br/>与解析依赖"]
B --> C["生成 HTML 与<br/>组件 JavaScript"]
C --> D["浏览器显示<br/>正文与初始界面"]
D --> E["组件进入视口<br/>加载 JavaScript"]
E --> F["完成 hydration<br/>响应组件交互"]
Astro renders UI framework components to HTML by default. A client:* directive controls when a component’s JavaScript is sent to the browser and hydration begins. 因此,在 MDX 中调用一个 React 组件,并不意味着整个页面都会变成需要大量 JavaScript 的客户端应用。Astro:Front-end frameworks
例如,已有一个正确导入的 React Counter 组件时,下列是 Astro MDX 的调用片段:
import Counter from '../components/Counter.jsx'
<Counter />
<Counter client:load />
<Counter client:visible />
它们依次表示:仅生成初始 HTML;页面加载时加载并执行组件 JavaScript;进入视口时加载并执行。片段需要工程已安装 React 集成且提供 Counter.jsx,不包含组件实现。client:* 是 Astro 的指令,不能据此推断其他 MDX 环境或 Obsidian 插件有同样行为。Astro:Client directives
想先体验组件与正文共存,可以打开本站 Labs,操作 HeroUI 示例,再看同页的 Astro 静态提示框。这个页面由站点原生 MDX 组织内容;它展示的是具体组件的能力,MDX 负责把组件嵌入文章结构。
Astro 的支持具体到哪一步
Astro 通过官方 @astrojs/mdx 集成支持 .mdx 页面、组件导入和内容集合中的 MDX。需要使用 React、Svelte 等组件时,还要接入相应框架的 integration。普通 .astro 组件可直接参与 Astro 的 MDX 渲染。Astro:MDX integration · Astro:Content collections
以下是一个已存在的 Astro 工程中的最小接入示例,演示静态组件与 Markdown 混排。先使用官方命令添加 MDX integration;已有主题或 integration 已经添加 MDX 时,应检查配置,避免重复注册。
npx astro add mdx
基础配置的关键部分如下。已有工程应把 mdx() 合并进现有 integrations,保留其他配置。
// astro.config.mjs
import {defineConfig} from 'astro/config'
import mdx from '@astrojs/mdx'
export default defineConfig({
integrations: [mdx()],
})
页面外壳 src/layouts/Article.astro:
---
const {frontmatter} = Astro.props
---
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<title>{frontmatter.title}</title>
</head>
<body><main><slot /></main></body>
</html>
复用组件 src/components/Notice.astro:
---
const {title} = Astro.props
---
<aside aria-label={title}>
<strong>{title}</strong>
<slot />
</aside>
正文 src/pages/mdx-demo.mdx:
---
title: MDX with Astro
layout: ../layouts/Article.astro
---
import Notice from '../components/Notice.astro'
export const total = 2 + 3
# MDX with Astro
Computed total: {total}.
<Notice title="Build-time content">
This paragraph supports **Markdown** inside an Astro component.
</Notice>
在该工程执行 npx astro dev 后访问 /mdx-demo/,应看到计算结果 5 和包含加粗文字的提示框。执行 npx astro build 后,这些内容直接存在于 HTML 中;示例没有需要 hydration 的组件。MDX 的 YAML 区域保存 frontmatter,JavaScript 的 import / export 写在该区域之外。这里的 layout 是 src/pages/ 独立内容页的约定,使用内容集合时不能假定它自动套用布局。Astro:Markdown layouts
上述 Astro 示例以 Node.js 26.0.0、Astro 7.3.1、@astrojs/mdx 8.0.0 完成本地构建与 HTML 校验;这是验证所用组合,不是最低版本要求。前面的独立 MDX 示例另外使用 @mdx-js/mdx 3.1.1 编译和渲染校验。
外部内容仓库还需要导入链路
Astro 支持 MDX,不代表任意从磁盘读取的 .mdx 字符串都会自动编译。若内容管线只是“读取文件 → 普通 Markdown 渲染 → 插入 HTML 字符串”,就没有完成组件导入、依赖解析与 MDX 模块渲染。
对于独立内容仓库,接入时通常要明确三件事:让文件进入 Astro 支持的编译与路由机制;约定组件可用的稳定导入路径;保留原有标题、链接、目录与搜索所需的静态内容。这是根据 MDX 编译模型得出的工程要求,不能仅靠把 .md 重命名为 .mdx 完成。MDX:Using MDX · Astro:Content collections
Obsidian 的支持要分层看
Obsidian 的官方文件格式列表将 Markdown 对应为 .md,没有把 .mdx 列为原生 Markdown 格式;额外文件类型可以通过社区插件扩展。Obsidian:Accepted file formats
截至整理日期,以下插件提供的能力不同:
| 使用层次 | 支持情况 | 实际边界 |
|---|---|---|
创建和编辑 .mdx | Edit MDX 可以像 .md 一样创建、编辑 | 作者明确说明不负责 MDX 预览 |
| 编译与部分 JSX 预览 | MDX Preview 可编译 MDX,提供 JSX 和 Code Hike 预览 | 使用插件自己的渲染环境 |
| 从应用工程导入的自定义 React 组件 | MDX Preview 无法解析应用自己的组件 | 显示带说明的占位内容,不能还原站点组件效果 |
Astro 组件、样式和 client:* 行为 | 需要实际 Astro 工程验证 | 不能由插件中的预览成功推断站点效果一致 |
| Backlinks、Graph、搜索及其他插件协作 | 需要按文件类型与插件组合逐项确认 | 能打开文件不等于知识库功能与 .md 完全等价 |
前两项分别见 Edit MDX 作者说明 与 MDX Preview 作者说明,它们也已列入 Edit MDX 社区目录 和 MDX Preview 社区目录。MDX Preview 会在带有会话确认的隔离 iframe 中执行 MDX JavaScript;这进一步说明它提供了自己的运行环境,并非复用了 Astro 项目的完整构建配置。
关于索引,Anything as Markdown 将非 .md 文件的索引支持标为实验性能力。因此,若依赖 Obsidian 的链接关系、搜索和其他插件,应先用少量样本检查这些具体功能,不能只看扩展名是否已经出现在文件列表中。Anything as Markdown 作者说明
比较稳妥的写作分工是:Obsidian 处理文字与笔记组织,代码编辑器维护组件,Astro 预览确认最终网页。 如果日常写作高度依赖 Obsidian 的完整 Markdown 体验,保留大部分文章为 .md,仅让确实需要组件的页面使用 .mdx,通常更容易维护。
从 Markdown 迁移时,容易踩哪些坑
MDX preserves much of Markdown’s syntax, but it is not a drop-in replacement for every Markdown file. In particular, < and { can start JSX or JavaScript syntax. 普通文稿里能直接显示的字符,到了 MDX 中可能触发解析错误。MDX:Troubleshooting
| 原有写法或习惯 | 迁移时的处理 |
|---|---|
| 正文里直接写花括号、模板占位符 | 使用行内代码、代码块或转义,避免被当作 JavaScript expressions |
HTML 的 <br>、未闭合标签、随意嵌套 | 按 JSX 规则自闭合或正确配对,例如 <br /> |
<!-- comment --> | 改为 MDX 的 {/* comment */} |
| 在 YAML frontmatter 中写 JavaScript | 将 import / export 移到 frontmatter 之外 |
| 缩进表示代码块 | 改用围栏代码块,避免与 JSX 排版缩进混淆 |
| 旧模板、shortcode、特殊内部链接语法 | 为 MDX 配置相应转换,不能假定原 Markdown 插件都能原样复用 |
在 React JSX 中为 HTML 元素设置 CSS class 时使用 className;自定义组件接受哪些 props 则由组件接口决定。迁移旧 HTML 时,要同时检查 MDX 语法与目标组件所接受的属性,不能将 React 的规则推广到所有框架集成。MDX:Syntax · Astro:Framework component props
正文中写 const x = 1 不会因为扩展名是 .mdx 就自动变成模块声明;需要使用合法的 ESM 导出、组件内部代码或表达式。较长逻辑放回组件或普通模块,文章只保留理解示例所需的调用。
还有一个实质性的边界:MDX 内容可以执行代码。从不可信来源收集文章时,不能把直接编译并执行任意 MDX 当作普通文本渲染。@mdx-js/mdx 官方文档明确提醒,evaluate 会执行 JavaScript;内容来源及可导入模块需要按代码依赖管理。MDX:Security
哪些文章值得采用 MDX
下面是基于写作与维护成本的选择建议。
| 内容目标 | 建议 |
|---|---|
| 长期知识笔记、普通教程、图文记录 | 优先 Markdown,便于在不同工具间阅读和编辑 |
| 只需要公式、Mermaid、代码高亮 | 先检查现有 Markdown 渲染能力 |
| 需要嵌入可操作的图表、参数实验或组件示例 | 考虑 MDX,让演示与解释位于同一阅读位置 |
| 多篇文章共用提示框、对比卡片或数据视图 | 考虑 MDX,并维护稳定的组件 props |
| 演示复杂、可以独立使用或需要单独布局 | 保留 Markdown 文章,链接或嵌入独立演示页也很合适 |
推荐让 .md 与 .mdx 按文章需要共存。组件接口尽量小而稳定:文章提供标题、参数和少量数据,组件负责展示及行为。这样既能利用 MDX 的组合能力,也能控制内容对工程细节的依赖。
相关入口
- Frontend 工具链导航:继续阅读构建与前端工具资料。
- MDX Playground:修改 MDX,观察渲染结果与编译输出。
- 本站 Labs:直接操作页面中的组件示例。