跳转到导航
4-5 分钟阅读
作者:Titus Wormer

快速开始

本文解释了如何将 MDX 集成到你的项目中。 它展示了如何使用你选择的打包器和 JSX 运行时。 要了解 MDX 格式的工作原理, 我们建议你先阅读§ 什么是 MDX。 如果你已经配置好并准备使用 MDX,请参见§ 使用 MDX

目录

前置条件

MDX 依赖 JSX, 因此你的项目也需要支持 JSX。 任何 JSX 运行时(React、Preact、Vue 等)都可以。 请注意,我们会为你将 JSX 编译为 JavaScript,所以你不需要自行配置。

所有 @mdx-js/* 包都是用现代 JavaScript 编写的。 需要 Node.js 16 或更高版本才能使用。 我们的包也是仅支持 ESM 的。

注意:使用 Rust 而非 Node.js? 试试 mdxjs-rs

快速入门

打包器

MDX 是一种编译为 JavaScript 的语言。 (我们也编译普通 Markdown 为 JavaScript。) 最简单的入门方式是使用你的打包器的集成(如果你有的话):

  • 如果你使用 esbuild(或 Bun), 安装并配置 @mdx-js/esbuild
  • 如果你使用 Rollup(或 Vite), 安装并配置 @mdx-js/rollup
  • 如果你使用 webpack(或 Next.js), 安装并配置 @mdx-js/loader

你也可以在不用打包器的情况下使用 MDX:

有关这些工具的更多信息, 请参见它们的专门章节: ¶ Next.js¶ Node.js¶ Rollup¶ Vite¶ esbuild¶ webpack

JSX

现在你已经设置了集成或 @mdx-js/mdx 本身, 是时候配置你的 JSX 运行时了。

其他 JSX 运行时通过设置 ProcessorOptions 中的 jsxImportSource 来支持。

有关这些工具的更多信息, 请参见它们的专门章节: ¶ Emotion¶ Preact¶ React¶ Solid¶ Svelte¶ Theme UI¶ Vue

编辑器

你可以通过在编辑器中添加 MDX 支持来提升使用体验:

为我们的 VS Code 扩展提供语法高亮、并在 GitHub 上用于高亮代码块的语法高亮 维护于 wooorm/markdown-tm-language

类型

展开类型化导入的示例

首先安装包:

Shell
npm install @types/mdx

…TypeScript 应该会自动识别:

example.js
import Post from './post.mdx' // `Post` 现在有类型了。
(alias) function Post(props: MDXProps): Element
import Post

An function component which renders the MDX content using JSX.

  • @param props This value is be available as the named variable props inside the MDX component.
  • @returns A JSX element. The meaning of this may depend on the project configuration. I.e. it could be a React, Preact, or Vuex element.

我们的包使用 TypeScript 进行类型标注。 要让类型工作, JSX 命名空间必须被类型化。 这通过安装和使用你框架的类型来完成, 例如 @types/react, 然后增强 mdx/types.js 模块。

example.ts
import * as React from 'react'

declare module 'mdx/types.js' {
  export import JSX = React.JSX
}
(alias) namespace React
import React
(alias) namespace JSX
import JSX = JSX
(alias) namespace React
import React
namespace JSX

要为导入的 .mdx.md 等启用类型, 安装并使用 @types/mdx。 这个包还导出了几个有用的类型, 例如 MDXComponents,它代表 components 属性。 你可以这样导入它们:

example.ts
import type {MDXComponents} from 'mdx/types.js'
(alias) type MDXComponents = NestedMDXComponents & {
    [x: string]: Component<JSX.IntrinsicElements> | undefined;
} & {
    wrapper?: Component<any>;
}
import MDXComponents

MDX components may be passed as the components.

The key is the name of the element to override. The value is the component to render instead.

安全

MDX 是一种编程语言。 如果你信任你的作者, 那没问题。 如果你不信任, 那就不安全。

不要让互联网上的随机人员编写 MDX。 如果你这样做, 你可能需要考虑使用带 sandbox<iframe>, 但安全很难, 而且这似乎不是 100% 安全的。 对于 Node.js, vm2 听起来不错。 但你可能还需要使用 Docker 或类似工具对整个操作系统进行沙箱化, 执行速率限制, 并确保进程在耗时过长时可以被终止。

集成

打包器

esbuild
展开示例
example.js
import mdx from '@mdx-js/esbuild'
import esbuild from 'esbuild'

await esbuild.build({
  entryPoints: ['index.mdx'],
  format: 'esm',
  outfile: 'output.js',
  plugins: [mdx({/* jsxImportSource: …, otherOptions… */})]
})
(alias) function mdx(options?: Readonly<Options> | null | undefined): esbuild.Plugin
import mdx

Create an esbuild plugin to compile MDX to JS.

esbuild takes care of turning modern JavaScript features into syntax that works wherever you want it to. With other integrations you might need to use Babel for this, but with esbuild that’s not needed. See esbuild’s docs for more info.

  • @param options Configuration (optional).
  • @return Plugin.
import esbuild
import esbuild
function build<{
    entryPoints: string[];
    format: "esm";
    outfile: string;
    plugins: esbuild.Plugin[];
}>(options: esbuild.SameShape<esbuild.BuildOptions, {
    entryPoints: string[];
    format: "esm";
    outfile: string;
    plugins: esbuild.Plugin[];
}>): Promise<esbuild.BuildResult<{
    entryPoints: string[];
    format: "esm";
    outfile: string;
    plugins: esbuild.Plugin[];
}>>

This function invokes the "esbuild" command-line tool for you. It returns a promise that either resolves with a "BuildResult" object or rejects with a "BuildFailure" object.

  • Works in node: yes
  • Works in browser: yes

Documentation: https://esbuild.github.io/api/#build

(property) entryPoints: string[]
(property) format: "esm"
(property) outfile: string
(property) plugins: esbuild.Plugin[]
(alias) mdx(options?: Readonly<Options> | null | undefined): esbuild.Plugin
import mdx

Create an esbuild plugin to compile MDX to JS.

esbuild takes care of turning modern JavaScript features into syntax that works wherever you want it to. With other integrations you might need to use Babel for this, but with esbuild that’s not needed. See esbuild’s docs for more info.

  • @param options Configuration (optional).
  • @return Plugin.

我们支持 esbuild。 安装并配置 esbuild 插件 @mdx-js/esbuild。 根据你使用的运行时(React、Preact、Vue 等)配置你的 JSX 运行时

要使用比你用户支持的更现代的 JavaScript 特性, 配置 esbuild 的 target

另见 ¶ Bun, 你可能正在使用它, 获取更多信息。

Rollup
展开示例
rollup.config.js
/**
 * @import {RollupOptions} from 'rollup'
 */

import mdx from '@mdx-js/rollup'
import {babel} from '@rollup/plugin-babel'

/** @type {RollupOptions} */
const config = {
  // …
  plugins: [
    // …
    mdx({/* jsxImportSource: …, otherOptions… */}),
    // Babel 是可选的:
    babel({
      // Also run on what used to be `.mdx` (but is now JS):
      extensions: ['.js', '.jsx', '.cjs', '.mjs', '.md', '.mdx'],
      // Other options…
    })
  ]
}

export default config
(alias) function mdx(options?: Readonly<Options> | null | undefined): Plugin
import mdx

Plugin to compile MDX w/ rollup.

  • @param options Configuration (optional).
  • @return Rollup plugin.
(alias) function babel(options?: RollupBabelInputPluginOptions): Plugin
import babel

A Rollup plugin for seamless integration between Rollup and Babel.

  • @param options - Plugin options.
  • @returns Plugin instance.
const config: RollupOptions
  • @type {RollupOptions}
(property) InputOptions.plugins?: InputPluginOption
(alias) mdx(options?: Readonly<Options> | null | undefined): Plugin
import mdx

Plugin to compile MDX w/ rollup.

  • @param options Configuration (optional).
  • @return Rollup plugin.
(alias) babel(options?: RollupBabelInputPluginOptions): Plugin
import babel

A Rollup plugin for seamless integration between Rollup and Babel.

  • @param options - Plugin options.
  • @returns Plugin instance.
(property) RollupBabelInputPluginOptions.extensions?: string[]

An array of file extensions that Babel should transpile. If you want to transpile TypeScript files with this plugin it's essential to include .ts and .tsx in this option.

  • @default ['.js', '.jsx', '.es6', '.es', '.mjs']
const config: RollupOptions
  • @type {RollupOptions}

我们支持 Rollup。 安装并配置 Rollup 插件 @mdx-js/rollup。 根据你使用的运行时(React、Preact、Vue 等)配置你的 JSX 运行时

要使用比你用户支持的更现代的 JavaScript 特性, 安装并配置 @rollup/plugin-babel

另见 ¶ Vite, 如果你通过它使用 Rollup, 获取更多信息。

Webpack
展开示例
webpack.config.js
/**
 * @import {Options} from '@mdx-js/loader'
 * @import {Configuration} from 'webpack'
 */

/** @type {Configuration} */
const webpackConfig = {
  module: {
    // …
    rules: [
      // …
      {
        test: /\.mdx?$/,
        use: [
          // Babel 是可选的:
          {loader: 'babel-loader', options: {}},
          {
            loader: '@mdx-js/loader',
            /** @type {Options} */
            options: {/* jsxImportSource: …, otherOptions… */}
          }
        ]
      }
    ]
  }
}

export default webpackConfig
const webpackConfig: Configuration
  • @type {Configuration}
(property) Configuration.module?: ModuleOptions

Options affecting the normal modules (NormalModuleFactory).

(property) ModuleOptions.rules?: (false | "" | 0 | RuleSetRule | "..." | null | undefined)[]

An array of rules applied for modules.

(property) RuleSetRule.test?: string | RegExp | ((value: string) => boolean) | RuleSetLogicalConditionsAbsolute | RuleSetConditionAbsolute[]

Shortcut for resource.test.

(property) RuleSetRule.use?: string | RuleSetUseFunction | (string | false | 0 | RuleSetUseFunction | {
    ident?: string;
    loader?: string;
    options?: string | {
        [index: string]: any;
    };
} | null | undefined)[] | {
    ident?: string;
    loader?: string;
    options?: string | {
        [index: string]: any;
    };
}

Modifiers applied to the module when rule is matched.

(property) loader?: string

Loader name.

(property) options?: string | {
    [index: string]: any;
}

Loader options.

(property) loader?: string

Loader name.

(property) options?: string | {
    [index: string]: any;
}

Loader options.

const webpackConfig: Configuration
  • @type {Configuration}

我们支持 webpack。 安装并配置 webpack loader @mdx-js/loader。 根据你使用的运行时(React、Preact、Vue 等)配置你的 JSX 运行时

要使用比你用户支持的更现代的 JavaScript 特性, 安装并配置 babel-loader

另见 ¶ Next.js, 如果你通过它使用 webpack, 获取更多信息。

构建系统

Vite
展开示例
vite.config.js
import mdx from '@mdx-js/rollup'
import {defineConfig} from 'vite'

const viteConfig = defineConfig({
  plugins: [
    mdx(/* jsxImportSource: …, otherOptions… */)
  ]
})

export default viteConfig
(alias) function mdx(options?: Readonly<Options> | null | undefined): Plugin
import mdx

Plugin to compile MDX w/ rollup.

  • @param options Configuration (optional).
  • @return Rollup plugin.
(alias) function defineConfig(config: UserConfig): UserConfig (+5 overloads)
import defineConfig

Type helper to make it easier to use vite.config.ts accepts a direct {@link UserConfig } object, or a function that returns it. The function receives a {@link ConfigEnv } object.

const viteConfig: UserConfig
(alias) defineConfig(config: UserConfig): UserConfig (+5 overloads)
import defineConfig

Type helper to make it easier to use vite.config.ts accepts a direct {@link UserConfig } object, or a function that returns it. The function receives a {@link ConfigEnv } object.

(property) UserConfig.plugins?: PluginOption[]

Array of vite plugins to use.

(alias) mdx(options?: Readonly<Options> | null | undefined): Plugin
import mdx

Plugin to compile MDX w/ rollup.

  • @param options Configuration (optional).
  • @return Rollup plugin.
const viteConfig: UserConfig

我们支持 Vite。 安装并配置 Rollup 插件 @mdx-js/rollup。 根据你使用的运行时(React、Preact、Vue 等)配置你的 JSX 运行时

要使用比你用户支持的更现代的 JavaScript 特性, 配置 Vite 的 build.target

注意:如果你同时使用 @vitejs/plugin-react, 你必须强制 @mdx-js/rollup 在它之前的 pre 阶段运行:

vite.config.js
// …
const viteConfig = defineConfig({
  plugins: [
    {enforce: 'pre', ...mdx({/* jsxImportSource: …, otherOptions… */})},
    react({include: /\.(jsx|js|mdx|md|tsx|ts)$/})
  ]
})
// …
const viteConfig: UserConfig
(alias) defineConfig(config: UserConfig): UserConfig (+5 overloads)
import defineConfig

Type helper to make it easier to use vite.config.ts accepts a direct {@link UserConfig } object, or a function that returns it. The function receives a {@link ConfigEnv } object.

(property) UserConfig.plugins?: PluginOption[]

Array of vite plugins to use.

(property) Plugin<any>.enforce?: "pre" | "post"

Enforce plugin invocation tier similar to webpack loaders. Hooks ordering is still subject to the order property in the hook object.

Plugin invocation order:

  • alias resolution
  • enforce: 'pre' plugins
  • vite core plugins
  • normal plugins
  • vite build plugins
  • enforce: 'post' plugins
  • vite build post plugins
(alias) mdx(options?: Readonly<Options> | null | undefined): Plugin
import mdx

Plugin to compile MDX w/ rollup.

  • @param options Configuration (optional).
  • @return Rollup plugin.
(alias) react(opts?: Options): Plugin[]
import react
(property) Options.include?: string | RegExp | (string | RegExp)[]

另见 Vite 中使用的 ¶ Rollup,如果你使用 Vue 请参见 ¶ Vue, 获取更多信息。

代码检查工具

ESLint

你可以使用 ESLinteslint-mdx 来检查你的 MDX 代码。

mdxlint

你可以使用 remark-lint 和其他 [remark 插件][]通过 mdxlint 来检查你的 MDX 代码。

编译器

Babel
展开插件和示例用法

此插件:

plugin.js
/**
 * @import {ParseResult, ParserOptions} from '@babel/parser'
 * @import {File} from '@babel/types'
 * @import {Program} from 'estree'
 * @import {Plugin} from 'unified'
 */

import parser from '@babel/parser'
import {compileSync} from '@mdx-js/mdx'
import estreeToBabel from 'estree-to-babel'

/**
 * Plugin that tells Babel to use a different parser.
 */
export function babelPluginSyntaxMdx() {
  return {parserOverride: babelParserWithMdx}
}

/**
 * Parser that handles MDX with `@mdx-js/mdx` and passes other things through
 * to the normal Babel parser.
 *
 * @param {string} value
 * @param {ParserOptions} options
 * @returns {ParseResult<File>}
 */
function babelParserWithMdx(value, options) {
  /** @type {string | undefined} */
  // @ts-expect-error: babel changed the casing at some point and the types are out of date.
  const filename = options.sourceFilename || options.sourceFileName

  if (filename && /\.mdx?$/.test(filename)) {
    // Babel does not support async parsers, unfortunately.
    const file = compileSync(
      {value, path: options.sourceFilename},
      {recmaPlugins: [recmaBabel] /* jsxImportSource: …, otherOptions… */}
    )
    return /** @type {ParseResult<File>} */ (file.result)
  }

  return parser.parse(value, options)
}

/**
 * A "recma" plugin is a unified plugin that runs on the estree (used by
 * `@mdx-js/mdx` and much of the JS ecosystem but not Babel).
 * This plugin defines `'estree-to-babel'` as the compiler,
 * which means that the resulting Babel tree is given back by `compileSync`.
 *
 * @type {Plugin<[], Program, unknown>}
 */
function recmaBabel() {
  // @ts-expect-error: `Program` is similar enough to a unist node.
  this.compiler = compiler

  /**
   * @param {Program} tree
   * @returns {unknown}
   */
  function compiler(tree) {
    // @ts-expect-error: TS2349: This expression *is* callable, `estreeToBabel` types are wrong.
    return estreeToBabel(tree)
  }
}
import parser
(alias) function compileSync(vfileCompatible: Readonly<Compatible>, compileOptions?: Readonly<CompileOptions> | null | undefined): VFile
import compileSync

Synchronously compile MDX to JS.

When possible please use the async compile.

  • @param vfileCompatible MDX document to parse.
  • @param compileOptions Compile configuration (optional).
  • @return Compiled file.
import estreeToBabel
function babelPluginSyntaxMdx(): {
    parserOverride: (value: string, options: parser.ParserOptions) => parser.ParseResult<File>;
}

Plugin that tells Babel to use a different parser.

(property) parserOverride: (value: string, options: parser.ParserOptions) => parser.ParseResult<File>
function babelParserWithMdx(value: string, options: parser.ParserOptions): parser.ParseResult<File>

Parser that handles MDX with @mdx-js/mdx and passes other things through to the normal Babel parser.

  • @param value
  • @param options
  • @returns
function babelParserWithMdx(value: string, options: parser.ParserOptions): parser.ParseResult<File>

Parser that handles MDX with @mdx-js/mdx and passes other things through to the normal Babel parser.

  • @param value
  • @param options
  • @returns
(parameter) value: string
  • @param value
(parameter) options: Partial<Options>
  • @param options
const filename: string | undefined
  • @type {string | undefined}
(parameter) options: Partial<Options>
  • @param options
(property) sourceFilename?: string | undefined

Correlate output AST nodes with their source filename. Useful when generating code and source maps from the ASTs of multiple input files.

(parameter) options: Partial<Options>
  • @param options
any
const filename: string | undefined
  • @type {string | undefined}
(method) RegExp.test(string: string): boolean

Returns a Boolean value that indicates whether or not a pattern exists in a searched string.

  • @param string String on which to perform the search.
const filename: string
  • @type {string | undefined}
const file: VFile
(alias) compileSync(vfileCompatible: Readonly<Compatible>, compileOptions?: Readonly<CompileOptions> | null | undefined): VFile
import compileSync

Synchronously compile MDX to JS.

When possible please use the async compile.

  • @param vfileCompatible MDX document to parse.
  • @param compileOptions Compile configuration (optional).
  • @return Compiled file.
(property) value: string
(property) path: string | undefined
(parameter) options: Partial<Options>
  • @param options
(property) sourceFilename?: string | undefined

Correlate output AST nodes with their source filename. Useful when generating code and source maps from the ASTs of multiple input files.

(property) recmaPlugins?: PluggableList | null | undefined

List of recma plugins (optional).

class recmaBabel
function recmaBabel(this: Processor): void | Transformer<Program, Node> | undefined

A "recma" plugin is a unified plugin that runs on the estree (used by @mdx-js/mdx and much of the JS ecosystem but not Babel). This plugin defines 'estree-to-babel' as the compiler, which means that the resulting Babel tree is given back by compileSync.

  • @type {Plugin<[], Program, unknown>}
const file: VFile
(property) VFile.result: unknown

Custom, non-string, compiled, representation.

This is used by unified to store non-string results. One example is when turning markdown into React nodes.

  • @type {unknown}
import parser
(alias) parse(input: string, options?: parser.ParserOptions): parser.ParseResult<File>
export parse

Parse the provided code as an entire ECMAScript program.

(parameter) value: string
  • @param value
(parameter) options: Partial<Options>
  • @param options
function recmaBabel(this: Processor): void | Transformer<Program, Node> | undefined

A "recma" plugin is a unified plugin that runs on the estree (used by @mdx-js/mdx and much of the JS ecosystem but not Babel). This plugin defines 'estree-to-babel' as the compiler, which means that the resulting Babel tree is given back by compileSync.

  • @type {Plugin<[], Program, unknown>}
(property) recmaBabel.compiler: (tree: Program) => unknown
(local function) compiler(tree: Program): unknown
  • @param tree
  • @returns
(local function) compiler(tree: Program): unknown
  • @param tree
  • @returns
(parameter) tree: Program
  • @param tree
import estreeToBabel
(parameter) tree: Program
  • @param tree

…可以像这样与 Babel API 一起使用:

example.js
import babel from '@babel/core'
import {babelPluginSyntaxMdx} from './plugin.js'

const document = '# Hello, world!'

// Note that a filename must be set for our plugin to know it's MDX instead of JS.
const result = await babel.transformAsync(document, {
  filename: 'example.mdx',
  plugins: [babelPluginSyntaxMdx]
})

console.log(result)
import babel
(alias) function babelPluginSyntaxMdx(): {
    parserOverride: (value: string, options: babel.ParserOptions) => ParseResult<babel.types.File>;
}
import babelPluginSyntaxMdx

Plugin that tells Babel to use a different parser.

const document: "# Hello, world!"
const result: babel.BabelFileResult | null
import babel
function transformAsync(code: string, opts?: babel.TransformOptions): Promise<babel.BabelFileResult | null>

Transforms the passed in code. Calling a callback with an object with the generated code, source map, and AST.

const document: "# Hello, world!"
(property) TransformOptions.filename?: string | null | undefined

Filename for use in errors etc

Default: "unknown"

(property) TransformOptions.plugins?: babel.PluginItem[] | null | undefined

List of plugins to load and use

Default: []

(alias) function babelPluginSyntaxMdx(): {
    parserOverride: (value: string, options: babel.ParserOptions) => ParseResult<babel.types.File>;
}
import babelPluginSyntaxMdx

Plugin that tells Babel to use a different parser.

namespace console
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
//   Error: Whoops, something bad happened
//     at [eval]:5:15
//     at Script.runInThisContext (node:vm:132:18)
//     at Object.runInThisContext (node:vm:309:38)
//     at node:internal/process/execution:77:19
//     at [eval]-wrapper:6:22
//     at evalScript (node:internal/process/execution:76:60)
//     at node:internal/main/eval_string:23:3

const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);

myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err

const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err
(method) Console.log(message?: any, ...optionalParams: any[]): void

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

  • @since v0.1.100
const result: babel.BabelFileResult | null

你可能应该直接使用 Rollup 或 webpack 而不是直接使用 Babel, 因为它们提供了更好的接口。 可以在 Babel 中使用 @mdx-js/mdx,而且会快一些, 因为它跳过了 @mdx-js/mdx 序列化和 Babel 解析(如果已经使用了 Babel 的话)。

Babel 不支持其解析器的语法扩展(它有"语法"插件, 但那些只是打开或关闭内部标志)。 它确实支持设置不同的解析器。 这反过来让我们选择是使用 @mdx-js/mdx 还是 @babel/parser

站点生成器

Astro

Astro 有自己的 MDX 集成。 你可以通过 Astro CLI 添加集成:npx astro add mdx

这个基础设置让你可以将 Markdown、Astro 组件和 MDX 文件作为 组件导入。 参见 Astro 的框架组件指南了解 如何在 MDX 文件中使用框架的组件。

有关如何结合 Astro 和 MDX 的更多信息, 请参见 Astro 的 MDX 集成文档

Docusaurus

Docusaurus 默认支持 MDX。 参见 Docusaurus 的 MDX 和 React 指南了解 如何在 Docusaurus 中使用 MDX。

Gatsby

Gatsby 有自己的插件来支持 MDX。 参见 gatsby-plugin-mdx 了解如何在 Gatsby 中使用 MDX。

Next.js
展开示例
next.config.js
import nextMdx from '@next/mdx'

const withMdx = nextMdx({
  // By default only the `.mdx` extension is supported.
  extension: /\.mdx?$/,
  options: {/* otherOptions… */}
})

const nextConfig = withMdx({
  // Support MDX files as pages:
  pageExtensions: ['md', 'mdx', 'tsx', 'ts', 'jsx', 'js'],
})

export default nextConfig
(alias) function nextMdx(options?: nextMdx.NextMDXOptions): WithMDX
(alias) namespace nextMdx
import nextMdx

Use MDX with Next.js

const withMdx: WithMDX
(alias) nextMdx(options?: nextMdx.NextMDXOptions): WithMDX
import nextMdx

Use MDX with Next.js

(property) nextMDX.NextMDXOptions.extension?: RuleSetConditionAbsolute

A webpack rule test to match files to treat as MDX.

  • @default /.mdx$/
  • @example // Support both .md and .mdx files. /.mdx?$/
(property) nextMDX.NextMDXOptions.options?: Options & {
    remarkPlugins?: (string | [name: string, options: any] | NonNullable<Options["remarkPlugins"]>[number])[] | Options["remarkPlugins"];
    rehypePlugins?: (string | [name: string, options: any] | NonNullable<Options["rehypePlugins"]>[number])[] | Options["rehypePlugins"];
}

The options to pass to MDX.

const nextConfig: NextConfig
const withMdx: (config: NextConfig) => NextConfig
(property) pageExtensions: string[]
const nextConfig: NextConfig

Next.js 有自己的 MDX 集成。 安装并配置 @next/mdx

不要使用 providerImportSource@mdx-js/react 来注入组件。 而是添加一个 mdx-components.tsx(在 src// 中)文件。 参见 nextjs.org 上的配置 MDX 获取更多信息。

Parcel

Parcel 有自己的插件来支持 MDX。 参见 @parcel/transformer-mdx 了解如何在 Parcel 中使用 MDX。

注意:官方 Parcel 插件目前未维护。 对于有维护的替代方案, 试试 parcel-transformer-mdx

JSX 运行时

Emotion
展开示例
example.js
import {compile} from '@mdx-js/mdx'

const js = String(await compile('# hi', {jsxImportSource: '@emotion/react', /* otherOptions… */}))
(alias) function compile(vfileCompatible: Readonly<Compatible>, compileOptions?: Readonly<CompileOptions> | null | undefined): Promise<VFile>
import compile

Compile MDX to JS.

  • @param vfileCompatible MDX document to parse.
  • @param compileOptions Compile configuration (optional).
  • @return Promise to compiled file.
const js: string
var String: StringConstructor
(value?: any) => string

Allows manipulation and formatting of text strings and determination and location of substrings within strings.

(alias) compile(vfileCompatible: Readonly<Compatible>, compileOptions?: Readonly<CompileOptions> | null | undefined): Promise<VFile>
import compile

Compile MDX to JS.

  • @param vfileCompatible MDX document to parse.
  • @param compileOptions Compile configuration (optional).
  • @return Promise to compiled file.
(property) jsxImportSource?: string | null | undefined

Place to import automatic JSX runtimes from (default: 'react'); when in the automatic runtime, this is used to define an import for Fragment, jsx, jsxDEV, and jsxs.

ProcessorOptions 中的 jsxImportSource 设置为 '@emotion/react' 时支持 Emotion。 你可以可选地安装和配置 @mdx-js/react 来 支持基于上下文的组件传递。

另见 Emotion 中使用的 ¶ React, 以及你可能使用的 ¶ Rollup¶ webpack, 获取更多信息。

Ink
展开示例
example.mdx
# Hi!
example.js
import React from 'react'
import {Text, render} from 'ink'
import Content from './example.mdx' // Assumes an integration is used to compile MDX -> JS.

render(
  React.createElement(Content, {
    components: {
      h1(properties) {
        return React.createElement(Text, {bold: true, ...properties})
      },
      p: Text
    }
  })
)
(alias) namespace React
import React
(alias) function Text({ color, backgroundColor, dimColor, bold, italic, underline, strikethrough, inverse, wrap, children, "aria-label": ariaLabel, "aria-hidden": ariaHidden, }: Props): React.JSX.Element | null
import Text

This component can display text and change its style to make it bold, underlined, italic, or strikethrough.

(alias) const render: (node: React.ReactNode, options?: NodeJS.WriteStream | RenderOptions) => Instance
import render

Mount a component and render the output.

(alias) function Content(props: MDXProps): Element
import Content

An function component which renders the MDX content using JSX.

  • @param props This value is be available as the named variable props inside the MDX component.
  • @returns A JSX element. The meaning of this may depend on the project configuration. I.e. it could be a React, Preact, or Vuex element.
(alias) render(node: React.ReactNode, options?: NodeJS.WriteStream | RenderOptions): Instance
import render

Mount a component and render the output.

(alias) namespace React
import React
function createElement<MDXProps>(type: React.FunctionComponent<MDXProps>, props?: (React.Attributes & MDXProps) | null | undefined, ...children: React.ReactNode[]): React.FunctionComponentElement<MDXProps> (+6 overloads)
(alias) function Content(props: MDXProps): Element
import Content

An function component which renders the MDX content using JSX.

  • @param props This value is be available as the named variable props inside the MDX component.
  • @returns A JSX element. The meaning of this may depend on the project configuration. I.e. it could be a React, Preact, or Vuex element.
(property) MDXProps.components?: MDXComponents

This prop may be used to customize how certain components are rendered.

(method) h1(properties: JSX.IntrinsicElements): React.FunctionComponentElement<Props>
(parameter) properties: JSX.IntrinsicElements
(alias) namespace React
import React
function createElement<Props>(type: React.FunctionComponent<Props>, props?: (React.Attributes & Props) | null | undefined, ...children: React.ReactNode[]): React.FunctionComponentElement<Props> (+6 overloads)
(alias) function Text({ color, backgroundColor, dimColor, bold, italic, underline, strikethrough, inverse, wrap, children, "aria-label": ariaLabel, "aria-hidden": ariaHidden, }: Props): React.JSX.Element | null
import Text

This component can display text and change its style to make it bold, underlined, italic, or strikethrough.

(property) bold?: boolean

Make the text bold.

(parameter) properties: JSX.IntrinsicElements
(property) p: ({ color, backgroundColor, dimColor, bold, italic, underline, strikethrough, inverse, wrap, children, "aria-label": ariaLabel, "aria-hidden": ariaHidden, }: Props) => React.JSX.Element | null
(alias) function Text({ color, backgroundColor, dimColor, bold, italic, underline, strikethrough, inverse, wrap, children, "aria-label": ariaLabel, "aria-hidden": ariaHidden, }: Props): React.JSX.Element | null
import Text

This component can display text and change its style to make it bold, underlined, italic, or strikethrough.

可以这样使用:

Shell
node --loader=@mdx-js/node-loader example.js

Ink 使用 React JSX 运行时, 所以请先设置好它。 你需要将 HTML 元素替换为 Ink 的组件。 参见 § 组件表 了解它们是什么,以及 Ink 的 文档了解可以用什么替换。

另见 ¶ Node.js¶ React 获取更多 信息。

Preact
展开示例
example.js
import {compile} from '@mdx-js/mdx'

const js = String(await compile('# hi', {jsxImportSource: 'preact', /* otherOptions… */}))
(alias) function compile(vfileCompatible: Readonly<Compatible>, compileOptions?: Readonly<CompileOptions> | null | undefined): Promise<VFile>
import compile

Compile MDX to JS.

  • @param vfileCompatible MDX document to parse.
  • @param compileOptions Compile configuration (optional).
  • @return Promise to compiled file.
const js: string
var String: StringConstructor
(value?: any) => string

Allows manipulation and formatting of text strings and determination and location of substrings within strings.

(alias) compile(vfileCompatible: Readonly<Compatible>, compileOptions?: Readonly<CompileOptions> | null | undefined): Promise<VFile>
import compile

Compile MDX to JS.

  • @param vfileCompatible MDX document to parse.
  • @param compileOptions Compile configuration (optional).
  • @return Promise to compiled file.
(property) jsxImportSource?: string | null | undefined

Place to import automatic JSX runtimes from (default: 'react'); when in the automatic runtime, this is used to define an import for Fragment, jsx, jsxDEV, and jsxs.

ProcessorOptions 中的 jsxImportSource 设置为 'preact' 时支持 Preact。 你可以可选地安装和配置 @mdx-js/preact 来 支持基于上下文的组件传递。

另见你可能使用的 ¶ Rollup¶ esbuild¶ webpack, 获取更多信息。

React

默认支持 React。 你可以可选地安装和配置 @mdx-js/react 来 支持基于上下文的组件传递。

另见你可能使用的 ¶ Rollup¶ esbuild¶ webpack, 获取更多信息。

Theme UI

Theme UI 有自己的插件来支持 MDX。 参见 @theme-ui/mdx 了解如何在 Theme UI 中使用 MDX。

Svelte
展开示例
example.js
import {compile} from '@mdx-js/mdx'

const js = String(await compile('# hi', {jsxImportSource: 'svelte-jsx', /* otherOptions… */}))
(alias) function compile(vfileCompatible: Readonly<Compatible>, compileOptions?: Readonly<CompileOptions> | null | undefined): Promise<VFile>
import compile

Compile MDX to JS.

  • @param vfileCompatible MDX document to parse.
  • @param compileOptions Compile configuration (optional).
  • @return Promise to compiled file.
const js: string
var String: StringConstructor
(value?: any) => string

Allows manipulation and formatting of text strings and determination and location of substrings within strings.

(alias) compile(vfileCompatible: Readonly<Compatible>, compileOptions?: Readonly<CompileOptions> | null | undefined): Promise<VFile>
import compile

Compile MDX to JS.

  • @param vfileCompatible MDX document to parse.
  • @param compileOptions Compile configuration (optional).
  • @return Promise to compiled file.
(property) jsxImportSource?: string | null | undefined

Place to import automatic JSX runtimes from (default: 'react'); when in the automatic runtime, this is used to define an import for Fragment, jsx, jsxDEV, and jsxs.

ProcessorOptions 中的 jsxImportSource 设置为 'svelte-jsx' 时支持 Svelte。

另见你可能使用的 ¶ Rollup¶ esbuild¶ webpack, 获取更多信息。

Vue
展开示例
example.js
import {compile} from '@mdx-js/mdx'

const js = String(await compile('# hi', {jsxImportSource: 'vue', /* otherOptions… */}))
(alias) function compile(vfileCompatible: Readonly<Compatible>, compileOptions?: Readonly<CompileOptions> | null | undefined): Promise<VFile>
import compile

Compile MDX to JS.

  • @param vfileCompatible MDX document to parse.
  • @param compileOptions Compile configuration (optional).
  • @return Promise to compiled file.
const js: string
var String: StringConstructor
(value?: any) => string

Allows manipulation and formatting of text strings and determination and location of substrings within strings.

(alias) compile(vfileCompatible: Readonly<Compatible>, compileOptions?: Readonly<CompileOptions> | null | undefined): Promise<VFile>
import compile

Compile MDX to JS.

  • @param vfileCompatible MDX document to parse.
  • @param compileOptions Compile configuration (optional).
  • @return Promise to compiled file.
(property) jsxImportSource?: string | null | undefined

Place to import automatic JSX runtimes from (default: 'react'); when in the automatic runtime, this is used to define an import for Fragment, jsx, jsxDEV, and jsxs.

ProcessorOptions 中的 jsxImportSource 设置为 'vue' 时支持 Vue。 你可以可选地安装和配置 @mdx-js/vue 来 支持基于上下文的组件传递。

另见你可能使用的 ¶ Vite, 获取更多信息。

Solid
展开示例
example.js
import {compile} from '@mdx-js/mdx'

const js = String(await compile('# hi', {jsxImportSource: 'solid-js/h', /* otherOptions… */}))
(alias) function compile(vfileCompatible: Readonly<Compatible>, compileOptions?: Readonly<CompileOptions> | null | undefined): Promise<VFile>
import compile

Compile MDX to JS.

  • @param vfileCompatible MDX document to parse.
  • @param compileOptions Compile configuration (optional).
  • @return Promise to compiled file.
const js: string
var String: StringConstructor
(value?: any) => string

Allows manipulation and formatting of text strings and determination and location of substrings within strings.

(alias) compile(vfileCompatible: Readonly<Compatible>, compileOptions?: Readonly<CompileOptions> | null | undefined): Promise<VFile>
import compile

Compile MDX to JS.

  • @param vfileCompatible MDX document to parse.
  • @param compileOptions Compile configuration (optional).
  • @return Promise to compiled file.
(property) jsxImportSource?: string | null | undefined

Place to import automatic JSX runtimes from (default: 'react'); when in the automatic runtime, this is used to define an import for Fragment, jsx, jsxDEV, and jsxs.

ProcessorOptions 中的 jsxImportSource 设置为 'solid-js/h' 时支持 Solid。

另见你可能使用的 ¶ Rollup¶ Vite, 获取更多信息。

JavaScript 引擎

Node.js

可以通过 @mdx-js/node-loader 在 Node 中导入 MDX 文件。 参见其 readme 了解如何配置。

Bun

可以通过 @mdx-js/esbuildBun 中导入 MDX 文件。

展开示例
bunfig.toml
preload = ["./bun-mdx.ts"]
bun-mdx.ts
import mdx from '@mdx-js/esbuild'
import {type BunPlugin, plugin} from 'bun'

await plugin(mdx() as unknown as BunPlugin)
(alias) function mdx(options?: Readonly<Options> | null | undefined): Plugin
import mdx

Create an esbuild plugin to compile MDX to JS.

esbuild takes care of turning modern JavaScript features into syntax that works wherever you want it to. With other integrations you might need to use Babel for this, but with esbuild that’s not needed. See esbuild’s docs for more info.

  • @param options Configuration (optional).
  • @return Plugin.
(alias) interface BunPlugin
import BunPlugin

A Bun plugin. Used for extending Bun's behavior at runtime, or with {@link Bun.build }

  • @category Bundler
(alias) const plugin: Bun.BunRegisterPlugin
import plugin
(alias) plugin<BunPlugin>(options: BunPlugin): void | Promise<void>
import plugin
(alias) mdx(options?: Readonly<Options> | null | undefined): Plugin
import mdx

Create an esbuild plugin to compile MDX to JS.

esbuild takes care of turning modern JavaScript features into syntax that works wherever you want it to. With other integrations you might need to use Babel for this, but with esbuild that’s not needed. See esbuild’s docs for more info.

  • @param options Configuration (optional).
  • @return Plugin.
(alias) interface BunPlugin
import BunPlugin

A Bun plugin. Used for extending Bun's behavior at runtime, or with {@link Bun.build }

  • @category Bundler

延伸阅读

MDX 用 ❤️ 在阿姆斯特丹、博伊西和全球各地打造
本站不会跟踪你。
MIT © 2017-2026
项目在 GitHub
网站在 GitHub
更新订阅 RSS
赞助 OpenCollective