跳转到内容

@astrojs/ mdx

Astro 集成 能够使用 MDX 组件,并允许你通过 .mdx 文件创建页面。

MDX 允许你在 Astro 项目的 Markdown 内容中使用变量、JSX 表达式和组件。如果你有现有的用 MDX 编写的内容,这个集成允许你把这些文件带到你的 Astro 项目中。

Astro 包含了一个 astro add 命令,用于自动设置官方集成。如果你愿意,可以改为手动安装集成

在新的终端窗口中运行下面其中一个命令。

Terminal window
npx astro add mdx

如果你遇到任何问题,请随时在 GitHub 上向我们报告并尝试下面的手动安装步骤。

首先,安装 @astrojs/mdx 包:

Terminal window
npm install @astrojs/mdx

然后,使用 integrations 属性将集成应用到你的 astro.config.* 文件中:

astro.config.mjs
import { defineConfig } from 'astro/config';
import mdx from '@astrojs/mdx';
export default defineConfig({
// ...
integrations: [mdx()],
});

对于 VS Code 的编辑器支持,请安装官方的 MDX 扩展

对于其他编辑器,请使用 MDX 语言服务器

访问 MDX 文档,了解如何使用标准 MDX 功能。

添加 MDX 集成可以使用 JSX 变量、表达式和组件来增强你的 Markdown 编写体验。

它还为标准 MDX 添加了额外的功能,包括对 MDX 中 Markdown 风格的 frontmatter 的支持。这允许你使用大部分 Astro 内置的 Markdown 功能

.mdx 文件必须使用 MDX 语法 而不能使用像 Astro 那样类 HTML 的语法编写。

在 MDX 中使用导出的变量

段落标题 在 MDX 中使用导出的变量

MDX 支持使用 export 语句将变量添加到 MDX 内容,或者将数据导出给需要引入它的组件。

例如,你可以从 MDX 页面或组件导出 title 字段以用作 {JSX 表达式} 的标题:

/src/blog/posts/post-1.mdx
export const title = '我的第一篇 MDX 博客'
# {title}

或者,你可以使用 importimport.meta.glob() 语句在页面中使用导出的 title

src/pages/index.astro
---
const matches = await import.meta.glob('./posts/*.mdx', { eager: true });
const posts = Object.values(posts);
---
{posts.map(post => <p>{post.title}</p>)}

当使用 import 语句或 import.meta.glob() 时,.astro 组件可以使用以下属性:

  • file - 文件的绝对路径(例如:/home/user/projects/.../file.mdx)。
  • url - 页面的 URL(例如:/zh-cn/guides/markdown-content)。
  • frontmatter - 包含了文件的 YAML frontmatter 中所指定的任何数据。
  • getHeadings() - 一个异步函数,用于返回文件中所有标题(<h1><h6>)的数组,类型为:{ depth: number; slug: string; text: string }[]。每个标题的 slug 都对应了给定标题生成的 ID,可用于锚点链接。
  • <Content /> - 返回文件完整渲染内容的组件。
  • (任意的 export 值) - MDX 文件还可以使用 export 语句以导出数据。

在 MDX 中使用 Frontmatter 变量

段落标题 在 MDX 中使用 Frontmatter 变量

Astro MDX 集成默认支持在 MDX 中使用 frontmatter。在 Markdown 文件中添加 frontmatter 属性,这些变量可在模板中以及在导入文件时以命名属性的形式访问。

/src/blog/posts/post-1.mdx
---
title: '我的第一篇 MDX 博客'
author: 'Houston'
---
# {frontmatter.title}
作者:{frontmatter.author}

安装 MDX 集成后,你可以在 MDX (.mdx) 文件中导入并使用 Astro 组件UI 框架组件。就像在任何其他 Astro 组件中使用它们一样。

别忘了在你的 UI 框架组件上添加 client:directive,如果需要的话!

MDX 文档中查看有关使用导入和导出语句的更多示例。

src/blog/post-1.mdx
---
title: 我的第一篇博客
---
import ReactCounter from '../components/ReactCounter.jsx';
我刚开始折腾一个新的 Astro 博客!
这是我的计数器组件,它在 MDX 中工作:
<ReactCounter client:load />

使用导入的 MDX 自定义组件

段落标题 使用导入的 MDX 自定义组件

渲染导入的 MDX 内容时,可以通过 components 属性传递 自定义组件

src/pages/page.astro
---
import { Content, components } from '../content.mdx';
import Heading from '../Heading.astro';
---
<!-- 为 # 语法创建自定义<h1>, _并且_ 在`content.mdx`中应用任何自定义组件 -->
<Content components={{...components, h1: Heading }} />

将自定义组件分配给 HTML 元素

段落标题 将自定义组件分配给 HTML 元素

使用 MDX,你可以将 Markdown 语法映射到自定义组件,而不是它们的标准 HTML 元素。这允许你以标准的 Markdown 语法编写,但是将特殊的组件样式应用于所选的元素。

将自定义组件导入 .mdx文件,然后将标准 HTML 元素映射到自定义组件的 components 对象以导出:

src/blog/posts/post-1.mdx
import Blockquote from '../components/Blockquote.astro';
export const components = {blockquote: Blockquote}
> 这个引用将是自定义引用块组件。
src/components/Blockquote.astro
---
const props = Astro.props;
---
<blockquote {...props} class="bg-blue-50 p-4">
<span class="text-4xl text-blue-600 mb-2"></span>
<slot /> <!-- 请务必为子组件添加 `<slot/>`! -->
</blockquote>

访问 MDX 网站,了解可以覆盖为自定义组件的 HTML 元素的完整列表。

一旦 MDX 集成被安装,在你的 Astro 项目中使用 .mdx 文件就不需要配置。

你可以通过以下选项配置你的 MDX 的渲染方式:

继承自 Markdown 配置的选项

段落标题 继承自 Markdown 配置的选项

所有 markdown 配置选项都可以在 MDX 集成中单独配置。这包括 remark 和 rehype 插件、语法高亮等。选项将默认为你的 Markdown 配置中的选项(请参阅 extendMarkdownConfig 选项来修改此选项)。

astro.config.mjs
import { defineConfig } from 'astro/config';
import mdx from '@astrojs/mdx';
import remarkToc from 'remark-toc';
import rehypePresetMinify from 'rehype-preset-minify';
export default defineConfig({
// ...
integrations: [
mdx({
syntaxHighlight: 'shiki',
shikiConfig: { theme: 'dracula' },
remarkPlugins: [remarkToc],
rehypePlugins: [rehypePresetMinify],
remarkRehype: { footnoteLabel: 'Footnotes' },
gfm: false,
}),
],
});
参见 Markdown 选项参考 以获得完整的选项列表。
  • 类型: boolean
  • 默认值: true

MDX 将默认扩展你的项目现有的 Markdown 配置。要覆盖个别选项,你可以在你的 MDX 配置中进行等价配置。

例如,假设你需要禁用 GitHub-Flavored Markdown,并为 MDX 文件应用一套不同的注释插件。你可以像这样应用这些选项,extendMarkdownConfig 默认为启用:

astro.config.mjs
import { defineConfig } from 'astro/config';
import mdx from '@astrojs/mdx';
export default defineConfig({
// ...
markdown: {
syntaxHighlight: 'prism',
remarkPlugins: [remarkPlugin1],
gfm: true,
},
integrations: [
mdx({
// 继承自 Markdown 的 `syntaxHighlight`
// Markdown `remarkPlugins` 被忽略,
// 只启用 `remarkPlugin2`。
remarkPlugins: [remarkPlugin2],
// `gfm` 被重写为 `false`
gfm: false,
}),
],
});

你可能还需要在 MDX 中禁用 markdown 配置扩展。为此,将 extendMarkdownConfig 设置为 false

astro.config.mjs
import { defineConfig } from 'astro/config';
import mdx from '@astrojs/mdx';
export default defineConfig({
// ...
markdown: {
remarkPlugins: [remarkPlugin1],
},
integrations: [
mdx({
// Markdown 配置现在被忽略了
extendMarkdownConfig: false,
// `remarkPlugins` 没有启用
}),
],
});

这些是直接修改输出 estree 的插件。这对于在你的 MDX 文件中修改或注入 JavaScript 变量很有用。

我们建议使用 AST Explorer来处理 estree 的输出,并尝试 estree-util-visit 来搜索整个 JavaScript 节点。

  • 类型: boolean | { ignoreElementNames?: string[] }

这是一个可选的配置设置,用于优化 MDX 输出,以便通过内部 rehype 插件加快构建和渲染速度。如果你的 MDX 文件较多,并注意到构建速度较慢,这可能会很有用。不过,该选项可能会生成一些未转义的 HTML,因此请确保你网站的交互式部分在启用该选项后仍能正常工作。

默认情况下是禁用的。要启用 MDX 优化,请在 MDX 集成配置中添加以下内容:

astro.config.mjs
import { defineConfig } from 'astro/config';
import mdx from '@astrojs/mdx';
export default defineConfig({
// ...
integrations: [
mdx({
optimize: true,
}),
],
});
  • 类型: string[]

添加于: @astrojs/mdx@3.0.0

以前称为 customComponentNames

optimize 的一个可选属性,用于防止 MDX 优化器处理某些元素名称,例如通过 components 属性传递给导入的 MDX 内容的自定义组件

你需要将这些组件从优化中排除,因为优化器会急切地将内容转换为静态字符串,这将破坏需要动态呈现的自定义组件。

例如,以下内容的预期 MDX 输出应为 <Heading>...</Heading>,而不是每个 "<h1>...</h1>"

---
import { Content, components } from '../content.mdx';
import Heading from '../Heading.astro';
---
<Content components={{ ...components, h1: Heading }} />

要使用 ignoreElementNames 属性配置此优化,指定应视为自定义组件的 HTML 元素名称数组:

astro.config.mjs
import { defineConfig } from 'astro/config';
import mdx from '@astrojs/mdx';
export default defineConfig({
// ...
integrations: [
mdx({
optimize: {
// 防止优化器处理 `h1` 元素
ignoreElementNames: ['h1'],
},
}),
],
});

请注意,如果你的 MDX 文件使用 export const components = {...} 配置自定义组件,则你无需手动配置此选项。优化器将自动检测它们。

更多集成

UI 框架

SSR 适配器

其他集成

贡献

你有什么想法?

社区