@astrojs/ mdx
这个 Astro 集成 使得你可以使用 MDX 组件,并允许你用 .mdx
文件创建页面。
为什么选择 MDX?
名为“为什么选择 MDX?”的部分MDX 允许你在 Astro 的 Markdown 内容中使用变量、JSX 表达式和组件。如果你有已使用 MDX 编写的现有内容,此集成允许你将这些文件引入到你的 Astro 项目中。
Astro 包含一个 astro add
命令来自动设置官方集成。如果你愿意,也可以手动安装集成。
在新的终端窗口中运行以下命令之一。
npx astro add mdx
pnpm astro add mdx
yarn astro add mdx
如果你遇到任何问题,请随时在 GitHub 上向我们报告,并尝试下面的手动安装步骤。
手动安装
名为“手动安装”的部分首先,安装 @astrojs/mdx
包
npm install @astrojs/mdx
pnpm add @astrojs/mdx
yarn add @astrojs/mdx
然后,使用 integrations
属性将此集成应用到你的 astro.config.*
文件中:
import { defineConfig } from 'astro/config';import mdx from '@astrojs/mdx';
export default defineConfig({ // ... integrations: [mdx()],});
编辑器集成
名为“编辑器集成”的部分要在 VS Code 中获得编辑器支持,请安装官方 MDX 扩展。
对于其他编辑器,请使用 MDX 语言服务器。
访问 MDX 文档以了解如何使用标准的 MDX 功能。
在 Astro 中使用 MDX
名为“在 Astro 中使用 MDX”的部分添加 MDX 集成可以通过 JSX 变量、表达式和组件来增强你的 Markdown 编写体验。
它还为标准 MDX 添加了额外的功能,包括支持 MDX 中的 Markdown 风格的 frontmatter。这使你可以使用 Astro 的大部分内置 Markdown 功能。
.mdx
文件必须使用 MDX 语法编写,而不是 Astro 的类 HTML 语法。
在内容集合中使用 MDX
名为“在内容集合中使用 MDX”的部分要在内容集合中包含 MDX 文件,请确保你的集合加载器已配置为从 .mdx
文件加载内容
import { defineCollection, z } from 'astro:content';import { glob } from 'astro/loaders';
const blog = defineCollection({ loader: glob({ pattern: "**/*.{md,mdx}", base: "./src/blog" }), schema: z.object({ title: z.string(), description: z.string(), pubDate: z.coerce.date(), })});
export const collections = { blog };
在 MDX 中使用导出的变量
名为“在 MDX 中使用导出的变量”的部分MDX 支持使用 export
语句向 MDX 内容添加变量,或将数据导出到导入它的组件中。
例如,你可以从 MDX 页面或组件中导出一个 title
字段,并使用 {JSX 表达式}
将其用作标题
export const title = 'My first MDX post'
# {title}
或者你可以在页面中使用 import
和 import.meta.glob()
语句来使用导出的 title
---const matches = import.meta.glob('./posts/*.mdx', { eager: true });const posts = Object.values(matches);---
{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/TOML 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 属性,这些变量可以在模板中使用,也可以在其他地方导入文件时作为命名属性使用。
---title: 'My first MDX post'author: 'Houston'---
# {frontmatter.title}
Written by: {frontmatter.author}
在 MDX 中使用组件
名为“在 MDX 中使用组件”的部分安装 MDX 集成后,你可以在 MDX(.mdx
)文件中导入和使用 Astro 组件和UI 框架组件,就像在任何其他 Astro 组件中使用它们一样。
如果需要,不要忘记在你的 UI 框架组件上包含 client:directive
!
在 MDX 文档中查看更多使用导入和导出语句的示例。
---title: My first post---import ReactCounter from '../components/ReactCounter.jsx';
I just started my new Astro blog!
Here is my counter component, working in MDX:<ReactCounter client:load />
使用导入的 MDX 的自定义组件
名为“使用导入的 MDX 的自定义组件”的部分渲染导入的 MDX 内容时,可以通过 components
prop 传递自定义组件。
---import { Content, components } from '../content.mdx';import Heading from '../Heading.astro';---<!-- Creates a custom <h1> for the # syntax, _and_ applies any custom components defined in `content.mdx` --><Content components={{...components, h1: Heading }} />
在 MDX 文件中定义和导出的自定义组件必须被导入,然后通过 components
属性传回给 <Content />
组件。
将自定义组件分配给 HTML 元素
名为“将自定义组件分配给 HTML 元素”的部分使用 MDX,你可以将 Markdown 语法映射到自定义组件,而不是它们的标准 HTML 元素。这使你可以使用标准的 Markdown 语法编写,但对选定的元素应用特殊的组件样式。
将你的自定义组件导入到你的 .mdx
文件中,然后导出一个 components
对象,该对象将标准 HTML 元素映射到你的自定义组件
import Blockquote from '../components/Blockquote.astro';export const components = {blockquote: Blockquote}
> This quote will be a custom Blockquote
---const props = Astro.props;---<blockquote {...props} class="bg-blue-50 p-4"> <span class="text-4xl text-blue-600 mb-2">“</span> <slot /> <!-- Be sure to add a `<slot/>` for child content! --></blockquote>
请访问 MDX 网站,查看可以作为自定义组件覆盖的 HTML 元素的完整列表。
安装 MDX 集成后,在 Astro 项目中使用 .mdx
文件无需额外配置。
你可以使用以下选项配置 MDX 的渲染方式
从 Markdown 配置继承的选项
名为“从 Markdown 配置继承的选项”的部分所有的 markdown
配置选项都可以在 MDX 集成中单独配置。这包括 remark 和 rehype 插件、语法高亮等等。默认情况下,这些选项将继承你的 Markdown 配置(参见 extendMarkdownConfig
选项来修改此行为)。
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, }), ],});
MDX 不支持将 remark 和 rehype 插件作为字符串传递。你应该安装、导入并应用插件函数。
extendMarkdownConfig
名为“extendMarkdownConfig”的部分- 类型:
boolean
- 默认值:
true
默认情况下,MDX 会扩展你项目的现有 Markdown 配置。要覆盖单个选项,你可以在 MDX 配置中指定它们等效的选项。
例如,假设你需要禁用 GitHub-Flavored Markdown 并为 MDX 文件应用一组不同的 remark 插件。你可以像这样应用这些选项,默认情况下 extendMarkdownConfig
是启用的
import { defineConfig } from 'astro/config';import mdx from '@astrojs/mdx';
export default defineConfig({ // ... markdown: { syntaxHighlight: 'prism', remarkPlugins: [remarkPlugin1], gfm: true, }, integrations: [ mdx({ // `syntaxHighlight` inherited from Markdown
// Markdown `remarkPlugins` ignored, // only `remarkPlugin2` applied. remarkPlugins: [remarkPlugin2], // `gfm` overridden to `false` gfm: false, }), ],});
你可能还需要在 MDX 中禁用 markdown
配置扩展。为此,请将 extendMarkdownConfig
设置为 false
import { defineConfig } from 'astro/config';import mdx from '@astrojs/mdx';
export default defineConfig({ // ... markdown: { remarkPlugins: [remarkPlugin1], }, integrations: [ mdx({ // Markdown config now ignored extendMarkdownConfig: false, // No `remarkPlugins` applied }), ],});
recmaPlugins
名为“recmaPlugins”的部分这些是直接修改输出的 estree 的插件。这对于在 MDX 文件中修改或注入 JavaScript 变量很有用。
我们建议使用 AST Explorer 来试验 estree 输出,并尝试使用 estree-util-visit
来搜索 JavaScript 节点。
optimize
名为“optimize”的部分- 类型:
boolean | { ignoreElementNames?: string[] }
这是一个可选的配置设置,通过内部的 rehype 插件来优化 MDX 输出,以加快构建和渲染速度。如果你有许多 MDX 文件并注意到构建速度缓慢,这可能会很有用。但是,此选项可能会生成一些未转义的 HTML,因此请确保在启用它后,你网站的交互部分仍然正常工作。
默认情况下,此功能是禁用的。要启用 MDX 优化,请将以下内容添加到你的 MDX 集成配置中
import { defineConfig } from 'astro/config';import mdx from '@astrojs/mdx';
export default defineConfig({ // ... integrations: [ mdx({ optimize: true, }), ],});
ignoreElementNames
名为“ignoreElementNames”的部分- 类型:
string[]
添加于: @astrojs/mdx@3.0.0
以前称为 customComponentNames
。
optimize
的一个可选属性,用于防止 MDX 优化器处理某些元素名称,例如通过 components prop 传递给导入的 MDX 内容的自定义组件。
你需要从优化中排除这些组件,因为优化器会急切地将内容转换为静态字符串,这将破坏需要动态渲染的自定义组件。
例如,以下内容的预期 MDX 输出是在每个 "<h1>...</h1>"
的位置上输出 <Heading>...</Heading>
---import { Content, components } from '../content.mdx';import Heading from '../Heading.astro';---
<Content components={{ ...components, h1: Heading }} />
要使用 ignoreElementNames
属性为此配置优化,请指定一个应被视为自定义组件的 HTML 元素名称数组
import { defineConfig } from 'astro/config';import mdx from '@astrojs/mdx';
export default defineConfig({ // ... integrations: [ mdx({ optimize: { // Prevent the optimizer from handling `h1` elements ignoreElementNames: ['h1'], }, }), ],});
请注意,如果你的 MDX 文件使用 export const components = { ... }
配置自定义组件,则无需手动配置此选项。优化器将自动检测它们。
- Astro MDX 入门模板展示了如何在你的 Astro 项目中使用 MDX 文件。