中文文档 / 入门
本文讲解了如何将 MDX 集成到您的项目中。 还展示了如何将 MDX 与您所使用的打包工具(bundler)和 JSX 运行时协同使用。 如需了解 MDX 格式的工作原理, 我们建议您先去阅读 § MDX 是什么 章节。 当您已经准备好使用 MDX 时,请参考 § 使用 MDX 章节。
MDX 依赖 JSX, 因此您的项目也得是支持 JSX 的。 任何 JSX 运行时(React、Preact、Vue 等)都可以。 注意,我们会为您把 JSX 编译成 JavaScript,因此您不必再做相关设置 了。
所有 @mdx-js/*
匹配的软件包都是使用最新的 JavaScript 语法编写的。 MDX 支持 Node.js 16.0 或更高版本。 我们提供的软件包全是支持 ESM 格式 的, 因此你必须使用 import
而不是 require
。
注意: 如果你使用的是 Rust 而不是 Node.js? 请试一试 mdxjs-rs
!
MDX 是一种编译成 JavaScript 的语言。 (我们还将普通的 markdown 也编译为 JavaScript。) 最简单的入门方法就是使用一个针对您所使用的打包工具的The easiest way to get started is to use an integration for your bundler if you have one:
@mdx-js/esbuild
@mdx-js/rollup
@mdx-js/loader
You can also use MDX without bundlers:
@mdx-js/node-loader
@mdx-js/mdx
to compile MDX files@mdx-js/mdx
to evaluate (compile and run) MDX filesFor more info on these tools, see their dedicated sections: ¶ Next.js, ¶ Node.js, ¶ Rollup, ¶ Vite, ¶ esbuild, and ¶ webpack.
Now you’ve set up an integration or @mdx-js/mdx
itself, it’s time to configure your JSX runtime.
@mdx-js/react
jsxImportSource
in ProcessorOptions
to 'preact'
; optionally install and configure @mdx-js/preact
svelte-jsx
, and set jsxImportSource
in ProcessorOptions
to 'svelte-jsx'
jsxImportSource
in ProcessorOptions
to 'vue'
; optionally install and configure @mdx-js/vue
jsxImportSource
in ProcessorOptions
to 'solid-js/h'
jsxImportSource
in ProcessorOptions
to '@emotion/react'
@mdx-js/react
, then wrap your MDX content in a <ThemeProvider />
Other JSX runtimes are supported by setting jsxImportSource
in ProcessorOptions
.
For more info on these tools, see their dedicated sections: ¶ Emotion, ¶ Preact, ¶ React, ¶ Solid, ¶ Svelte, ¶ Theme UI, and ¶ Vue.
通过为你所使用的编辑器添加对 MDX 的支持,能够增强使用 MDX 的 体验:
mdx-js/mdx-analyzer
jxnblk/vim-mdx-js
jonsuh/mdx-sublime
JetBrains/mdx-intellij-plugin
The syntax highlighting that powers our VS Code extension and that is used to highlight code blocks on GitHub is maintained at wooorm/markdown-tm-language
.
First install the package:
npm install @types/mdx
…TypeScript should automatically pick it up:
import Post from './post.mdx' // `Post` is now typed.
(alias) function Post(props: MDXProps): JSX.Element
import Post
An function component which renders the MDX content using JSX.
props
inside the MDX component.Our packages are typed with TypeScript. For types to work, the JSX
namespace must be typed. This is done by installing and using the types of your framework, such as @types/react
.
To enable types for imported .mdx
, .md
, etc., install and use @types/mdx
. This package also exports several useful types, such as MDXComponents
which represents the components
prop. You can import them like so:
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。 如果你这样做了, 你需要考虑使用带有 沙箱
的 <iframe>
, 但安全性仍很难保证, 而且似乎也不是 100% 安全。 对于 Node.js, vm2 听起来很有趣。 不过,你还是应该使用 Docker 之类的工具对整个操作系统进行沙箱化, 以执行速率限制, 并确保进程耗时过长时可以被杀死。
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.
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<...>
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.
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.
We support esbuild. Install and configure the esbuild plugin @mdx-js/esbuild
. Configure your JSX runtime depending on which one (React, Preact, Vue, etc.) you use.
To use more modern JavaScript features than what your users support, configure esbuild’s target
.
See also ¶ Bun, which you might be using, for more info.
/**
* @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 is optional:
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.
(alias) function babel(options?: RollupBabelInputPluginOptions): Plugin
import babel
A Rollup plugin for seamless integration between Rollup and Babel.
const config: RollupOptions
(property) InputOptions.plugins?: InputPluginOption
(alias) mdx(options?: Readonly<Options> | null | undefined): Plugin
import mdx
Plugin to compile MDX w/ rollup.
(alias) babel(options?: RollupBabelInputPluginOptions): Plugin
import babel
A Rollup plugin for seamless integration between Rollup and Babel.
(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.
const config: RollupOptions
我们提供了对 Rollup 的支持。 您只需安装并配置 Rollup 插件 @mdx-js/rollup
即可。 对 JSX 运行时的配置 取决于你所使用的是哪个框架(React、Preact、Vue、 等)。
如果你所使用的 JavaScript 语法太新,你的用户所用的环境可能不支持, 那么你需要 安装并配置 @rollup/plugin-babel
插件。
如果你通过 ¶ Vite, 来使用 Rollup, 请参阅此链接。
/**
* @import {Options} from '@mdx-js/loader'
* @import {Configuration} from 'webpack'
*/
/** @type {Configuration} */
const webpackConfig = {
module: {
// …
rules: [
// …
{
test: /\.mdx?$/,
use: [
// Babel is optional:
{loader: 'babel-loader', options: {}},
{
loader: '@mdx-js/loader',
/** @type {Options} */
options: {/* jsxImportSource: …, otherOptions… */}
}
]
}
]
}
}
export default webpackConfig
const webpackConfig: 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 | (string | false | 0 | {
ident?: string;
loader?: string;
options?: string | {
[index: string]: any;
};
} | ((data: object) => string | {
ident?: string;
loader?: string;
options?: string | {
[index: string]: any;
};
} | __TypeWebpackOptions | __Type_2[]) | null | undefined)[] | ((data: {
resource: string;
realResource: string;
resourceQuery: string;
issuer: string;
compiler: string;
}) => __Type_2[]) | {
...;
} | __TypeWebpackOptions
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
我们提供了对 webpack 的支持。 你只需要安装并配置 webpack 加载器(loader) @mdx-js/loader
即可。 对 JSX 运行时的配置 取决于你所使用的是哪个框架(React、Preact、Vue、 等)。
如果你所使用的 JavaScript 语法太新,你的用户所用的环境可能不支持, 那么你需要 安装并配置 babel-loader
插件。
如果你使用的是 ¶ Next.js, 并且同时使用了 webpack, 请参阅此链接。
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.
(alias) function defineConfig(config: UserConfig): UserConfig (+3 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 (+3 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.
const viteConfig: UserConfig
我们提供了对 Vite 的支持。 你只需要安装并配置 Rollup 插件 @mdx-js/rollup
即可。 对 JSX 运行时的配置 取决于你所使用的是哪个框架(React、Preact、Vue、 等)。
如果你所使用的 JavaScript 语法太新,你的用户所用的环境可能不支持, 请配置 Vite 的 build.target
。
Note: If you also use @vitejs/plugin-react
, you must force @mdx-js/rollup
to run in the pre
phase before it:
// …
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 (+3 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:
enforce: 'pre'
pluginsenforce: 'post'
plugins(alias) mdx(options?: Readonly<Options> | null | undefined): Plugin
import mdx
Plugin to compile MDX w/ rollup.
(alias) react(opts?: Options): PluginOption[]
import react
(property) Options.include?: string | RegExp | (string | RegExp)[]
See also ¶ Rollup which is used in Vite and see ¶ Vue if you’re using that, for more info.
This plugin:
/**
* @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: any, compileOptions?: Readonly<CompileOptions> | null | undefined): VFile
import compileSync
Synchronously compile MDX to JS.
When possible please use the async compile
.
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.
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.
(parameter) value: string
(parameter) options: parser.ParserOptions
const filename: string | undefined
(parameter) options: parser.ParserOptions
(property) ParserOptions.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: parser.ParserOptions
any
const filename: string | undefined
(method) RegExp.test(string: string): boolean
Returns a Boolean value that indicates whether or not a pattern exists in a searched string.
const filename: string
const file: VFile
(alias) compileSync(vfileCompatible: any, compileOptions?: Readonly<CompileOptions> | null | undefined): VFile
import compileSync
Synchronously compile MDX to JS.
When possible please use the async compile
.
(property) value: string
(property) path: string | undefined
(parameter) options: parser.ParserOptions
(property) ParserOptions.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); this is a new ecosystem, currently in beta, to transform esast trees (JavaScript)
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
.
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.
import parser
(alias) parse(input: string, options?: ParserOptions): ParseResult<File>
export parse
Parse the provided code as an entire ECMAScript program.
(parameter) value: string
(parameter) options: parser.ParserOptions
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
.
(property) recmaBabel.compiler: (tree: Program) => unknown
(local function) compiler(tree: Program): unknown
(local function) compiler(tree: Program): unknown
(parameter) tree: Program
import estreeToBabel
(parameter) tree: Program
…can be used like so with the Babel API:
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:
Console
class with methods such as console.log()
, console.error()
and console.warn()
that can be used to write to any Node.js stream.console
instance configured to write to process.stdout
and process.stderr
. The global console
can be used without calling require('console')
.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.
const result: babel.BabelFileResult | null
You should probably use Rollup or webpack instead of Babel directly as that gives the best interface. It is possible to use @mdx-js/mdx
in Babel and it’s a bit faster, as it skips @mdx-js/mdx
serialization and Babel parsing, if Babel is used anyway.
Babel does not support syntax extensions to its parser (it has “syntax” plugins but those only turn internal flags on or off). It does support setting a different parser. Which in turn lets us choose whether to use the @mdx-js/mdx
or @babel/parser
.
Astro has its own MDX integration. You can add the integration with the Astro CLI: npx astro add mdx
.
This base setup lets you import markdown, Astro components, and MDX files as components. See Astro’s Framework components guide for info on how to use components from frameworks in your MDX files.
For more on how to combine Astro and MDX, see Astro’s MDX integration docs.
Docusaurus supports MDX by default. See Docusaurus’ MDX and React guide for info on how to use MDX with Docusaurus.
Gatsby has its own plugin to support MDX. See gatsby-plugin-mdx
on how to use MDX with Gatsby.
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
const withMdx: WithMDX
(property) nextMDX.NextMDXOptions.extension?: RuleSetConditionAbsolute
A webpack rule test to match files to treat as MDX.
(property) nextMDX.NextMDXOptions.options?: Options
The options to pass to MDX.
const nextConfig: NextConfig
const withMdx: (config: NextConfig) => NextConfig
(property) pageExtensions: string[]
const nextConfig: NextConfig
Next.js has its own MDX integration. Install and configure @next/mdx
.
Do not use providerImportSource
and @mdx-js/react
with Next to inject components. Add an mdx-components.tsx
(in src/
or /
) file instead. See Configuring MDX on nextjs.org
for more info.
Parcel has its own plugin to support MDX. See @parcel/transformer-mdx
on how to use MDX with Parcel.
import {compile} from '@mdx-js/mdx'
const js = String(await compile('# hi', {jsxImportSource: '@emotion/react', /* otherOptions… */}))
(alias) function compile(vfileCompatible: any, compileOptions?: Readonly<CompileOptions> | null | undefined): Promise<VFile>
import compile
Compile MDX to JS.
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: any, compileOptions?: Readonly<CompileOptions> | null | undefined): Promise<VFile>
import compile
Compile MDX to JS.
(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
.
Emotion is supported when jsxImportSource
in ProcessorOptions
is set to '@emotion/react'
. You can optionally install and configure @mdx-js/react
to support context based component passing.
See also ¶ React, which is used in Emotion, and see ¶ Rollup and ¶ webpack, which you might be using, for more info.
# Hi!
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) {
// @ts-expect-error: `Ink` types don’t match w/ `exactOptionalPropertyTypes: true`
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, }: Props): React.JSX.Element | null
import Text
This component can display text, and change its style to make it colorful, bold, underline, 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.
props
inside the MDX component.(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 React.createElement(type: "input", props?: (React.InputHTMLAttributes<HTMLInputElement> & React.ClassAttributes<HTMLInputElement>) | null, ...children: React.ReactNode[]): React.DetailedReactHTMLElement<React.InputHTMLAttributes<HTMLInputElement>, HTMLInputElement> (+6 overloads)
(alias) function Content(props: MDXProps): Element
import Content
An function component which renders the MDX content using JSX.
props
inside the MDX component.(property) components: {
h1(properties: React.DetailedHTMLProps<React.HTMLAttributes<HTMLHeadingElement>, HTMLHeadingElement>): React.DetailedReactHTMLElement<React.InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>;
p: ({ color, backgroundColor, dimColor, bold, italic, underline, strikethrough, inverse, wrap, children, }: Props) => React.JSX.Element | null;
}
(method) h1(properties: React.DetailedHTMLProps<React.HTMLAttributes<HTMLHeadingElement>, HTMLHeadingElement>): React.DetailedReactHTMLElement<React.InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>
(parameter) properties: React.DetailedHTMLProps<React.HTMLAttributes<HTMLHeadingElement>, HTMLHeadingElement>
(alias) namespace React
import React
function React.createElement(type: "input", props?: (React.InputHTMLAttributes<HTMLInputElement> & React.ClassAttributes<HTMLInputElement>) | null, ...children: React.ReactNode[]): React.DetailedReactHTMLElement<React.InputHTMLAttributes<HTMLInputElement>, HTMLInputElement> (+6 overloads)
(alias) function Text({ color, backgroundColor, dimColor, bold, italic, underline, strikethrough, inverse, wrap, children, }: Props): React.JSX.Element | null
import Text
This component can display text, and change its style to make it colorful, bold, underline, italic or strikethrough.
(property) bold: boolean
(parameter) properties: React.DetailedHTMLProps<React.HTMLAttributes<HTMLHeadingElement>, HTMLHeadingElement>
No overload matches this call.
The last overload gave the following error.
Type '({ color, backgroundColor, dimColor, bold, italic, underline, strikethrough, inverse, wrap, children, }: Props) => Element | null' is not assignable to type 'Component<DetailedHTMLProps<HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>> | undefined'.
Type '({ color, backgroundColor, dimColor, bold, italic, underline, strikethrough, inverse, wrap, children, }: Props) => Element | null' is not assignable to type '(props: DetailedHTMLProps<HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>) => ReactNode'.
Types of parameters '__0' and 'props' are incompatible.
Type 'DetailedHTMLProps<HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>' is not assignable to type 'Props' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the types of the target's properties.
Types of property 'color' are incompatible.
Type 'string | undefined' is not assignable to type 'LiteralUnion<keyof ForegroundColor, string>'.
Type 'undefined' is not assignable to type 'LiteralUnion<keyof ForegroundColor, string>'. (2769)
(property) p: ({ color, backgroundColor, dimColor, bold, italic, underline, strikethrough, inverse, wrap, children, }: Props) => React.JSX.Element | null
(alias) function Text({ color, backgroundColor, dimColor, bold, italic, underline, strikethrough, inverse, wrap, children, }: Props): React.JSX.Element | null
import Text
This component can display text, and change its style to make it colorful, bold, underline, italic or strikethrough.
Can be used with:
node --loader=@mdx-js/node-loader example.js
Ink uses the React JSX runtime, so set that up. You will need to swap HTML elements out for Ink’s components. See § Table of components for what those are and Ink’s docs on what they can be replaced with.
See also ¶ Node.js and ¶ React for more info.
import {compile} from '@mdx-js/mdx'
const js = String(await compile('# hi', {jsxImportSource: 'preact', /* otherOptions… */}))
(alias) function compile(vfileCompatible: any, compileOptions?: Readonly<CompileOptions> | null | undefined): Promise<VFile>
import compile
Compile MDX to JS.
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: any, compileOptions?: Readonly<CompileOptions> | null | undefined): Promise<VFile>
import compile
Compile MDX to JS.
(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
.
Preact is supported when jsxImportSource
in ProcessorOptions
is set to 'preact'
. You can optionally install and configure @mdx-js/preact
to support context based component passing.
See also ¶ Rollup, ¶ esbuild, and ¶ webpack, which you might be using, for more info.
React is supported by default. You can optionally install and configure @mdx-js/react
to support context based component passing.
See also ¶ Rollup, ¶ esbuild, and ¶ webpack, which you might be using, for more info.
Theme UI has its own plugin to support MDX. See @theme-ui/mdx
on how to use MDX with Theme UI.
import {compile} from '@mdx-js/mdx'
const js = String(await compile('# hi', {jsxImportSource: 'svelte-jsx', /* otherOptions… */}))
(alias) function compile(vfileCompatible: any, compileOptions?: Readonly<CompileOptions> | null | undefined): Promise<VFile>
import compile
Compile MDX to JS.
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: any, compileOptions?: Readonly<CompileOptions> | null | undefined): Promise<VFile>
import compile
Compile MDX to JS.
(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
.
Svelte is supported when jsxImportSource
in ProcessorOptions
is set to 'svelte-jsx'
.
See also ¶ Rollup, ¶ esbuild, and ¶ webpack, which you might be using, for more info.
import {compile} from '@mdx-js/mdx'
const js = String(await compile('# hi', {jsxImportSource: 'vue', /* otherOptions… */}))
(alias) function compile(vfileCompatible: any, compileOptions?: Readonly<CompileOptions> | null | undefined): Promise<VFile>
import compile
Compile MDX to JS.
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: any, compileOptions?: Readonly<CompileOptions> | null | undefined): Promise<VFile>
import compile
Compile MDX to JS.
(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
.
Vue is supported when jsxImportSource
in ProcessorOptions
is set to 'vue'
. You can optionally install and configure @mdx-js/vue
to support context based component passing.
See also ¶ Vite, which you might be using, for more info.
import {compile} from '@mdx-js/mdx'
const js = String(await compile('# hi', {jsxImportSource: 'solid-js/h', /* otherOptions… */}))
(alias) function compile(vfileCompatible: any, compileOptions?: Readonly<CompileOptions> | null | undefined): Promise<VFile>
import compile
Compile MDX to JS.
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: any, compileOptions?: Readonly<CompileOptions> | null | undefined): Promise<VFile>
import compile
Compile MDX to JS.
(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
.
Solid is supported when jsxImportSource
in ProcessorOptions
is set to 'solid-js/h'
.
See also ¶ Rollup and ¶ Vite, which you might be using, for more info.
MDX files can be imported in Node by using @mdx-js/node-loader
. See its readme on how to configure it.
MDX files can be imported in Bun by using 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. 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.@mdx-js/esbuild
.Expand example
preload = ["./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
(alias) interface BunPlugin
import BunPlugin
(alias) const plugin: BunRegisterPlugin
import plugin
(alias) plugin<BunPlugin>(options: BunPlugin): void | Promise<void>
import plugin
(alias) mdx(options?: Readonly<Options> | null | undefined): Plugin
import mdx
(alias) interface BunPlugin
import BunPlugin