mirror of
https://github.com/Snigdha-OS/documentation.git
synced 2025-09-08 19:34:56 +02:00
1311 lines
38 KiB
Markdown
1311 lines
38 KiB
Markdown
# `@mdx-js/mdx`
|
||
|
||
[![Build][build-badge]][build]
|
||
[![Coverage][coverage-badge]][coverage]
|
||
[![Downloads][downloads-badge]][downloads]
|
||
[![Size][size-badge]][size]
|
||
[![Sponsors][sponsors-badge]][collective]
|
||
[![Backers][backers-badge]][collective]
|
||
[![Chat][chat-badge]][chat]
|
||
|
||
MDX compiler.
|
||
|
||
<!-- more -->
|
||
|
||
## Contents
|
||
|
||
* [What is this?](#what-is-this)
|
||
* [When should I use this?](#when-should-i-use-this)
|
||
* [Install](#install)
|
||
* [Use](#use)
|
||
* [API](#api)
|
||
* [`compile(file, options?)`](#compilefile-options)
|
||
* [`compileSync(file, options?)`](#compilesyncfile-options)
|
||
* [`createProcessor(options?)`](#createprocessoroptions)
|
||
* [`evaluate(file, options)`](#evaluatefile-options)
|
||
* [`evaluateSync(file, options)`](#evaluatesyncfile-options)
|
||
* [`nodeTypes`](#nodetypes)
|
||
* [`run(code, options)`](#runcode-options)
|
||
* [`runSync(code, options)`](#runsynccode-options)
|
||
* [`CompileOptions`](#compileoptions)
|
||
* [`EvaluateOptions`](#evaluateoptions)
|
||
* [`Fragment`](#fragment)
|
||
* [`Jsx`](#jsx)
|
||
* [`JsxDev`](#jsxdev)
|
||
* [`ProcessorOptions`](#processoroptions)
|
||
* [`RunOptions`](#runoptions)
|
||
* [`UseMdxComponents`](#usemdxcomponents)
|
||
* [Types](#types)
|
||
* [Architecture](#architecture)
|
||
* [Compatibility](#compatibility)
|
||
* [Security](#security)
|
||
* [Contribute](#contribute)
|
||
* [License](#license)
|
||
|
||
## What is this?
|
||
|
||
This package is a compiler that turns MDX into JavaScript.
|
||
It can also evaluate MDX code.
|
||
|
||
## When should I use this?
|
||
|
||
This is the core compiler for turning MDX into JavaScript which gives you the
|
||
most control.
|
||
If you’re using a bundler (Rollup, esbuild, webpack), a site builder (Next.js),
|
||
or build system (Vite) which comes with a bundler, you’re better off using an
|
||
integration: see [§ Integrations][integrations].
|
||
|
||
## Install
|
||
|
||
This package is [ESM only][esm].
|
||
In Node.js (version 16+), install with [npm][]:
|
||
|
||
```sh
|
||
npm install @mdx-js/mdx
|
||
```
|
||
|
||
In Deno with [`esm.sh`][esmsh]:
|
||
|
||
```tsx
|
||
import {compile} from 'https://esm.sh/@mdx-js/mdx@3'
|
||
```
|
||
|
||
In browsers with [`esm.sh`][esmsh]:
|
||
|
||
```html
|
||
<script type="module">
|
||
import {compile} from 'https://esm.sh/@mdx-js/mdx@3?bundle'
|
||
</script>
|
||
```
|
||
|
||
## Use
|
||
|
||
Say we have an MDX document, `example.mdx`:
|
||
|
||
```mdx
|
||
export function Thing() {
|
||
return <>World!</>
|
||
}
|
||
|
||
# Hello, <Thing />
|
||
```
|
||
|
||
…and some code in `example.js` to compile `example.mdx` to JavaScript:
|
||
|
||
```tsx
|
||
import fs from 'node:fs/promises'
|
||
import {compile} from '@mdx-js/mdx'
|
||
|
||
const compiled = await compile(await fs.readFile('example.mdx'))
|
||
|
||
console.log(String(compiled))
|
||
```
|
||
|
||
Yields roughly:
|
||
|
||
```tsx
|
||
import {Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs} from 'react/jsx-runtime'
|
||
|
||
export function Thing() {
|
||
return _jsx(_Fragment, {children: 'World!'})
|
||
}
|
||
|
||
function _createMdxContent(props) {
|
||
const _components = {h1: 'h1', ...props.components}
|
||
return _jsxs(_components.h1, {children: ['Hello, ', _jsx(Thing, {})]})
|
||
}
|
||
|
||
export default function MDXContent(props = {}) {
|
||
const {wrapper: MDXLayout} = props.components || {}
|
||
return MDXLayout
|
||
? _jsx(MDXLayout, {...props, children: _jsx(_createMdxContent, {...props})})
|
||
: _createMdxContent(props)
|
||
}
|
||
```
|
||
|
||
See [§ Using MDX][using-mdx] for more on how MDX work and how to use the result.
|
||
|
||
## API
|
||
|
||
This package exports the following identifiers:
|
||
[`compile`][api-compile],
|
||
[`compileSync`][api-compile-sync],
|
||
[`createProcessor`][api-create-processor],
|
||
[`evaluate`][api-evaluate],
|
||
[`evaluateSync`][api-evaluate-sync],
|
||
[`nodeTypes`][api-node-types],
|
||
[`run`][api-run], and
|
||
[`runSync`][api-run-sync].
|
||
There is no default export.
|
||
|
||
### `compile(file, options?)`
|
||
|
||
Compile MDX to JS.
|
||
|
||
###### Parameters
|
||
|
||
* `file` ([`Compatible` from `vfile`][vfile-compatible])
|
||
— MDX document to parse
|
||
* `options` ([`CompileOptions`][api-compile-options], optional)
|
||
— compile configuration
|
||
|
||
###### Returns
|
||
|
||
Promise to compiled file ([`Promise<VFile>`][vfile]).
|
||
|
||
###### Examples
|
||
|
||
The input value for `file` can be many different things.
|
||
You can pass a `string`, `Uint8Array` in UTF-8, [`VFile`][vfile], or anything
|
||
that can be given to `new VFile`.
|
||
|
||
```tsx
|
||
import {compile} from '@mdx-js/mdx'
|
||
import {VFile} from 'vfile'
|
||
|
||
await compile(':)')
|
||
await compile(Buffer.from(':-)'))
|
||
await compile({path: 'path/to/file.mdx', value: '🥳'})
|
||
await compile(new VFile({path: 'path/to/file.mdx', value: '🤭'}))
|
||
```
|
||
|
||
The output `VFile` can be used to access more than the generated code:
|
||
|
||
```tsx
|
||
import {compile} from '@mdx-js/mdx'
|
||
import remarkPresetLintConsistent from 'remark-preset-lint-consistent' // Lint rules to check for consistent markdown.
|
||
import {reporter} from 'vfile-reporter'
|
||
|
||
const file = await compile('*like this* or _like this_?', {remarkPlugins: [remarkPresetLintConsistent]})
|
||
|
||
console.error(reporter(file))
|
||
```
|
||
|
||
Yields:
|
||
|
||
```txt
|
||
1:16-1:27 warning Emphasis should use `*` as a marker emphasis-marker remark-lint
|
||
|
||
⚠ 1 warning
|
||
```
|
||
|
||
### `compileSync(file, options?)`
|
||
|
||
Synchronously compile MDX to JS.
|
||
|
||
When possible please use the async [`compile`][api-compile].
|
||
|
||
###### Parameters
|
||
|
||
* `file` ([`Compatible` from `vfile`][vfile-compatible])
|
||
— MDX document to parse
|
||
* `options` ([`CompileOptions`][api-compile-options], optional)
|
||
— compile configuration
|
||
|
||
###### Returns
|
||
|
||
Compiled file ([`VFile`][vfile]).
|
||
|
||
### `createProcessor(options?)`
|
||
|
||
Create a processor to compile markdown or MDX to JavaScript.
|
||
|
||
> **Note**: `format: 'detect'` is not allowed in `ProcessorOptions`.
|
||
|
||
###### Parameters
|
||
|
||
* `options` ([`ProcessorOptions`][api-processor-options], optional)
|
||
— process configuration
|
||
|
||
###### Returns
|
||
|
||
Processor ([`Processor` from `unified`][unified-processor]).
|
||
|
||
### `evaluate(file, options)`
|
||
|
||
[Compile][api-compile] and [run][api-run] MDX.
|
||
|
||
When you trust your content, `evaluate` can work.
|
||
When possible, use [`compile`][api-compile], write to a file, and then run with
|
||
Node or use one of the [§ Integrations][integrations].
|
||
|
||
> ☢️ **Danger**: it’s called **evaluate** because it `eval`s JavaScript.
|
||
|
||
###### Parameters
|
||
|
||
* `file` ([`Compatible` from `vfile`][vfile-compatible])
|
||
— MDX document to parse
|
||
* `options` ([`EvaluateOptions`][api-evaluate-options], **required**)
|
||
— configuration
|
||
|
||
###### Returns
|
||
|
||
Promise to a module ([`Promise<MDXModule>` from
|
||
`mdx/types.js`][mdx-types-module]).
|
||
|
||
The result is an object with a `default` field set to the component;
|
||
anything else that was exported is available too.
|
||
For example, assuming the contents of `example.mdx` from [§ Use][use] was in
|
||
`file`, then:
|
||
|
||
```tsx
|
||
import {evaluate} from '@mdx-js/mdx'
|
||
import * as runtime from 'react/jsx-runtime'
|
||
|
||
console.log(await evaluate(file, runtime))
|
||
```
|
||
|
||
…yields:
|
||
|
||
```tsx
|
||
{Thing: [Function: Thing], default: [Function: MDXContent]}
|
||
```
|
||
|
||
###### Notes
|
||
|
||
Compiling (and running) MDX takes time.
|
||
|
||
If you are live-rendering a string of MDX that often changes using a virtual DOM
|
||
based framework (such as React), one performance improvement is to call the
|
||
`MDXContent` component yourself.
|
||
The reason is that the `evaluate` creates a new function each time, which cannot
|
||
be diffed:
|
||
|
||
```diff
|
||
const {default: MDXContent} = await evaluate('…')
|
||
|
||
-<MDXContent {...props} />
|
||
+MDXContent(props)
|
||
```
|
||
|
||
### `evaluateSync(file, options)`
|
||
|
||
Compile and run MDX, synchronously.
|
||
|
||
When possible please use the async [`evaluate`][api-evaluate].
|
||
|
||
> ☢️ **Danger**: it’s called **evaluate** because it `eval`s JavaScript.
|
||
|
||
###### Parameters
|
||
|
||
* `file` ([`Compatible` from `vfile`][vfile-compatible])
|
||
— MDX document to parse
|
||
* `options` ([`EvaluateOptions`][api-evaluate-options], **required**)
|
||
— configuration
|
||
|
||
###### Returns
|
||
|
||
Module ([`MDXModule` from `mdx/types.js`][mdx-types-module]).
|
||
|
||
### `nodeTypes`
|
||
|
||
List of node types made by `mdast-util-mdx`, which have to be passed
|
||
through untouched from the mdast tree to the hast tree (`Array<string>`).
|
||
|
||
### `run(code, options)`
|
||
|
||
Run code compiled with `outputFormat: 'function-body'`.
|
||
|
||
> ☢️ **Danger**: this `eval`s JavaScript.
|
||
|
||
###### Parameters
|
||
|
||
* `code` ([`VFile`][vfile] or `string`)
|
||
— JavaScript function body to run
|
||
* `options` ([`RunOptions`][api-run-options], **required**)
|
||
— configuration
|
||
|
||
###### Returns
|
||
|
||
Promise to a module ([`Promise<MDXModule>` from
|
||
`mdx/types.js`][mdx-types-module]);
|
||
the result is an object with a `default` field set to the component;
|
||
anything else that was exported is available too.
|
||
|
||
###### Example
|
||
|
||
On the server:
|
||
|
||
```tsx
|
||
import {compile} from '@mdx-js/mdx'
|
||
|
||
const code = String(await compile('# hi', {outputFormat: 'function-body'}))
|
||
// To do: send `code` to the client somehow.
|
||
```
|
||
|
||
On the client:
|
||
|
||
```tsx
|
||
import {run} from '@mdx-js/mdx'
|
||
import * as runtime from 'react/jsx-runtime'
|
||
|
||
const code = '' // To do: get `code` from server somehow.
|
||
|
||
const {default: Content} = await run(code, {...runtime, baseUrl: import.meta.url})
|
||
|
||
console.log(Content)
|
||
```
|
||
|
||
…yields:
|
||
|
||
```tsx
|
||
[Function: MDXContent]
|
||
```
|
||
|
||
### `runSync(code, options)`
|
||
|
||
Run code, synchronously.
|
||
|
||
When possible please use the async [`run`][api-run].
|
||
|
||
> ☢️ **Danger**: this `eval`s JavaScript.
|
||
|
||
###### Parameters
|
||
|
||
* `code` ([`VFile`][vfile] or `string`)
|
||
— JavaScript function body to run
|
||
* `options` ([`RunOptions`][api-run-options], **required**)
|
||
— configuration
|
||
|
||
###### Returns
|
||
|
||
Module ([`MDXModule` from `mdx/types.js`][mdx-types-module]).
|
||
|
||
### `CompileOptions`
|
||
|
||
Configuration for `compile` (TypeScript type).
|
||
|
||
`CompileOptions` is the same as [`ProcessorOptions`][api-processor-options]
|
||
with the exception that the `format` option supports a `'detect'` value,
|
||
which is the default.
|
||
The `'detect'` format means to use `'md'` for files with an extension in
|
||
`mdExtensions` and `'mdx'` otherwise.
|
||
|
||
###### Type
|
||
|
||
```tsx
|
||
/**
|
||
* Configuration for `compile`
|
||
*/
|
||
type CompileOptions = Omit<ProcessorOptions, 'format'> & {
|
||
/**
|
||
* Format of `file` (default: `'detect'`).
|
||
*/
|
||
format?: 'detect' | 'md' | 'mdx' | null | undefined
|
||
}
|
||
```
|
||
|
||
### `EvaluateOptions`
|
||
|
||
Configuration for `evaluate` (TypeScript type).
|
||
|
||
`EvaluateOptions` is the same as [`CompileOptions`][api-compile-options],
|
||
except that the options `baseUrl`, `jsx`, `jsxImportSource`, `jsxRuntime`,
|
||
`outputFormat`, `pragma`, `pragmaFrag`, `pragmaImportSource`, and
|
||
`providerImportSource` are not allowed, and that
|
||
[`RunOptions`][api-run-options] are also used.
|
||
|
||
###### Type
|
||
|
||
```tsx
|
||
/**
|
||
* Configuration for `evaluate`.
|
||
*/
|
||
type EvaluateOptions = Omit<
|
||
CompileOptions,
|
||
| 'baseUrl' // Note that this is also in `RunOptions`.
|
||
| 'jsx'
|
||
| 'jsxImportSource'
|
||
| 'jsxRuntime'
|
||
| 'outputFormat'
|
||
| 'pragma'
|
||
| 'pragmaFrag'
|
||
| 'pragmaImportSource'
|
||
| 'providerImportSource'
|
||
> &
|
||
RunOptions
|
||
```
|
||
|
||
### `Fragment`
|
||
|
||
Represent the children, typically a symbol (TypeScript type).
|
||
|
||
###### Type
|
||
|
||
```ts
|
||
type Fragment = unknown
|
||
```
|
||
|
||
### `Jsx`
|
||
|
||
Create a production element (TypeScript type).
|
||
|
||
###### Parameters
|
||
|
||
* `type` (`unknown`)
|
||
— element type: `Fragment` symbol, tag name (`string`), component
|
||
* `properties` (`Properties`)
|
||
— element properties and `children`
|
||
* `key` (`string` or `undefined`)
|
||
— key to use
|
||
|
||
###### Returns
|
||
|
||
Element from your framework (`JSX.Element`).
|
||
|
||
### `JsxDev`
|
||
|
||
Create a development element (TypeScript type).
|
||
|
||
###### Parameters
|
||
|
||
* `type` (`unknown`)
|
||
— element type: `Fragment` symbol, tag name (`string`), component
|
||
* `properties` (`Properties`)
|
||
— element properties and `children`
|
||
* `key` (`string` or `undefined`)
|
||
— key to use
|
||
* `isStaticChildren` (`boolean`)
|
||
— whether two or more children are passed (in an array), which is whether
|
||
`jsxs` or `jsx` would be used
|
||
* `source` (`Source`)
|
||
— info about source
|
||
* `self` (`unknown`)
|
||
— context object (`this`)
|
||
|
||
### `ProcessorOptions`
|
||
|
||
Configuration for `createProcessor` (TypeScript type).
|
||
|
||
###### Fields
|
||
|
||
* `SourceMapGenerator` (`SourceMapGenerator` from [`source-map`][source-map],
|
||
optional)
|
||
— add a source map (object form) as the `map` field on the resulting file
|
||
|
||
<details><summary>Expand example</summary>
|
||
|
||
Assuming `example.mdx` from [§ Use][use] exists, then:
|
||
|
||
```tsx
|
||
import fs from 'node:fs/promises'
|
||
import {compile} from '@mdx-js/mdx'
|
||
import {SourceMapGenerator} from 'source-map'
|
||
|
||
const file = await compile(
|
||
{path: 'example.mdx', value: await fs.readFile('example.mdx')},
|
||
{SourceMapGenerator}
|
||
)
|
||
|
||
console.log(file.map)
|
||
```
|
||
|
||
…yields:
|
||
|
||
```tsx
|
||
{
|
||
file: 'example.mdx',
|
||
mappings: ';;aAAaA,QAAQ;YAAQ;;;;;;;;iBAE3B',
|
||
names: ['Thing'],
|
||
sources: ['example.mdx'],
|
||
version: 3
|
||
}
|
||
```
|
||
|
||
</details>
|
||
|
||
* `baseUrl` (`URL` or `string`, optional, example: `import.meta.url`)
|
||
— use this URL as `import.meta.url` and resolve `import` and
|
||
`export … from` relative to it
|
||
|
||
<details><summary>Expand example</summary>
|
||
|
||
Say we have a module `example.js`:
|
||
|
||
```tsx
|
||
import {compile} from '@mdx-js/mdx'
|
||
|
||
const code = 'export {number} from "./data.js"\n\n# hi'
|
||
const baseUrl = 'https://a.full/url' // Typically `import.meta.url`
|
||
|
||
console.log(String(await compile(code, {baseUrl})))
|
||
```
|
||
|
||
…now running `node example.js` yields:
|
||
|
||
```tsx
|
||
import {jsx as _jsx} from 'react/jsx-runtime'
|
||
export {number} from 'https://a.full/data.js'
|
||
function _createMdxContent(props) { /* … */ }
|
||
export default function MDXContent(props = {}) { /* … */ }
|
||
```
|
||
|
||
</details>
|
||
|
||
* `development` (`boolean`, default: `false`)
|
||
— whether to add extra info to error messages in generated code and use the
|
||
development automatic JSX runtime (`Fragment` and `jsxDEV` from
|
||
`/jsx-dev-runtime`);
|
||
when using the webpack loader (`@mdx-js/loader`) or the Rollup integration
|
||
(`@mdx-js/rollup`) through Vite, this is automatically inferred from how
|
||
you configure those tools
|
||
|
||
<details><summary>Expand example</summary>
|
||
|
||
Say we had some MDX that references a component that can be passed or
|
||
provided at runtime:
|
||
|
||
```mdx
|
||
**Note**<NoteIcon />: some stuff.
|
||
```
|
||
|
||
And a module to evaluate that:
|
||
|
||
```tsx
|
||
import fs from 'node:fs/promises'
|
||
import {evaluate} from '@mdx-js/mdx'
|
||
import * as runtime from 'react/jsx-runtime'
|
||
|
||
const path = 'example.mdx'
|
||
const value = await fs.readFile(path)
|
||
const MDXContent = (await evaluate({path, value}, {...runtime, baseUrl: import.meta.url})).default
|
||
|
||
console.log(MDXContent({}))
|
||
```
|
||
|
||
…running that would normally (production) yield:
|
||
|
||
```txt
|
||
Error: Expected component `NoteIcon` to be defined: you likely forgot to import, pass, or provide it.
|
||
at _missingMdxReference (eval at run (…/@mdx-js/mdx/lib/run.js:18:10), <anonymous>:27:9)
|
||
at _createMdxContent (eval at run (…/@mdx-js/mdx/lib/run.js:18:10), <anonymous>:15:20)
|
||
at MDXContent (eval at run (…/@mdx-js/mdx/lib/run.js:18:10), <anonymous>:9:9)
|
||
at main (…/example.js:11:15)
|
||
```
|
||
|
||
…but if we add `development: true` to our example:
|
||
|
||
```diff
|
||
@@ -7,6 +7,6 @@
|
||
import fs from 'node:fs/promises'
|
||
-import * as runtime from 'react/jsx-runtime'
|
||
+import * as runtime from 'react/jsx-dev-runtime'
|
||
import {evaluate} from '@mdx-js/mdx'
|
||
|
||
const path = 'example.mdx'
|
||
const value = await fs.readFile(path)
|
||
-const MDXContent = (await evaluate({path, value}, {...runtime, baseUrl: import.meta.url})).default
|
||
+const MDXContent = (await evaluate({path, value}, {development: true, ...runtime, baseUrl: import.meta.url})).default
|
||
|
||
console.log(MDXContent({}))
|
||
```
|
||
|
||
…and we’d run it again, we’d get:
|
||
|
||
```txt
|
||
Error: Expected component `NoteIcon` to be defined: you likely forgot to import, pass, or provide it.
|
||
It’s referenced in your code at `1:9-1:21` in `example.mdx`
|
||
provide it.
|
||
at _missingMdxReference (eval at run (…/@mdx-js/mdx/lib/run.js:18:10), <anonymous>:27:9)
|
||
at _createMdxContent (eval at run (…/@mdx-js/mdx/lib/run.js:18:10), <anonymous>:15:20)
|
||
at MDXContent (eval at run (…/@mdx-js/mdx/lib/run.js:18:10), <anonymous>:9:9)
|
||
at main (…/example.js:11:15)
|
||
```
|
||
|
||
</details>
|
||
|
||
* `elementAttributeNameCase` (`'html'` or `'react`, default: `'react'`)
|
||
— casing to use for attribute names;
|
||
HTML casing is for example `class`, `stroke-linecap`, `xml:lang`;
|
||
React casing is for example `className`, `strokeLinecap`, `xmlLang`;
|
||
for JSX components written in MDX, the author has to be aware of which
|
||
framework they use and write code accordingly;
|
||
for AST nodes generated by this project, this option configures it
|
||
|
||
* `format` (`'md'` or `'mdx'`, default: `'mdx'`)
|
||
— format of the file;
|
||
`'md'` means treat as markdown and `'mdx'` means treat as [MDX][mdx-syntax]
|
||
|
||
<details><summary>Expand example</summary>
|
||
|
||
```tsx
|
||
compile('…') // Seen as MDX.
|
||
compile('…', {format: 'mdx'}) // Seen as MDX.
|
||
compile('…', {format: 'md'}) // Seen as markdown.
|
||
```
|
||
|
||
</details>
|
||
|
||
* `jsx` (`boolean`, default: `false`)
|
||
— whether to keep JSX;
|
||
the default is to compile JSX away so that the resulting file is
|
||
immediately runnable.
|
||
|
||
<details><summary>Expand example</summary>
|
||
|
||
If `file` is the contents of `example.mdx` from [§ Use][use], then:
|
||
|
||
```tsx
|
||
compile(file, {jsx: true})
|
||
```
|
||
|
||
…yields this difference:
|
||
|
||
```diff
|
||
-import {Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs} from 'react/jsx-runtime'
|
||
+/*@jsxRuntime automatic*/
|
||
+/*@jsxImportSource react*/
|
||
|
||
export function Thing() {
|
||
- return _jsx(_Fragment, {children: 'World'})
|
||
+ return <>World!</>
|
||
}
|
||
|
||
function _createMdxContent(props) {
|
||
const _components = {
|
||
h1: 'h1',
|
||
...props.components
|
||
}
|
||
- return _jsxs(_components.h1, {children: ['Hello ', _jsx(Thing, {})]})
|
||
+ return <_components.h1>{"Hello "}<Thing /></_components.h1>
|
||
}
|
||
|
||
export default function MDXContent(props = {}) {
|
||
const {wrapper: MDXLayout} = props.components || {}
|
||
return MDXLayout
|
||
- ? _jsx(MDXLayout, {
|
||
- ...props,
|
||
- children: _jsx(_createMdxContent, props)
|
||
- })
|
||
+ ? <MDXLayout {...props}><_createMdxContent {...props} /></MDXLayout>
|
||
: _createMdxContent(props)
|
||
}
|
||
}
|
||
```
|
||
|
||
</details>
|
||
|
||
* `jsxImportSource` (`string`, default: `'react'`)
|
||
— place to import automatic JSX runtimes from;
|
||
when in the `automatic` runtime, this is used to define an import for
|
||
`Fragment`, `jsx`, `jsxDEV`, and `jsxs`
|
||
|
||
<details><summary>Expand example</summary>
|
||
|
||
If `file` is the contents of `example.mdx` from [§ Use][use], then:
|
||
|
||
```tsx
|
||
compile(file, {jsxImportSource: 'preact'})
|
||
```
|
||
|
||
…yields this difference:
|
||
|
||
```diff
|
||
-import {Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs} from 'react/jsx-runtime'
|
||
+import {Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from 'preact/jsx-runtime'
|
||
```
|
||
|
||
</details>
|
||
|
||
* `jsxRuntime` (`'automatic'` or `'classic'`, default: `'automatic'`)
|
||
— JSX runtime to use;
|
||
the automatic runtime compiles to `import _jsx from
|
||
'$importSource/jsx-runtime'\n_jsx('p')`;
|
||
the classic runtime compiles to calls such as `h('p')`
|
||
|
||
> 👉 **Note**: support for the classic runtime is deprecated and will
|
||
> likely be removed in the next major version.
|
||
|
||
<details><summary>Expand example</summary>
|
||
|
||
If `file` is the contents of `example.mdx` from [§ Use][use], then:
|
||
|
||
```tsx
|
||
compile(file, {jsxRuntime: 'classic'})
|
||
```
|
||
|
||
…yields this difference:
|
||
|
||
```diff
|
||
-import {Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs} from 'react/jsx-runtime'
|
||
+import React from 'react'
|
||
|
||
export function Thing() {
|
||
- return _jsx(_Fragment, {children: 'World'})
|
||
+ return React.createElement(React.Fragment, null, 'World!')
|
||
}
|
||
…
|
||
```
|
||
|
||
</details>
|
||
|
||
* `outputFormat` (`'function-body'` or `'program'`, default: `'program'`)
|
||
— output format to generate;
|
||
in most cases `'program'` should be used, it results in a whole program;
|
||
internally [`evaluate`][api-evaluate] uses `'function-body'` to compile to
|
||
code that can be passed to [`run`][api-run];
|
||
in some cases, you might want what `evaluate` does in separate steps, such
|
||
as when compiling on the server and running on the client.
|
||
|
||
<details><summary>Expand example</summary>
|
||
|
||
With a module `example.js`:
|
||
|
||
```tsx
|
||
import {compile} from '@mdx-js/mdx'
|
||
|
||
const code = 'export const no = 3.14\n\n# hi {no}'
|
||
|
||
console.log(String(await compile(code, {outputFormat: 'program'}))) // Default.
|
||
console.log(String(await compile(code, {outputFormat: 'function-body'})))
|
||
```
|
||
|
||
…yields:
|
||
|
||
```tsx
|
||
import {jsx as _jsx, jsxs as _jsxs} from 'react/jsx-runtime'
|
||
export const no = 3.14
|
||
function _createMdxContent(props) { /* … */ }
|
||
export default function MDXContent(props = {}) { /* … */ }
|
||
```
|
||
|
||
```tsx
|
||
'use strict'
|
||
const {Fragment: _Fragment, jsx: _jsx} = arguments[0]
|
||
const no = 3.14
|
||
function _createMdxContent(props) { /* … */ }
|
||
function MDXContent(props = {}) { /* … */ }
|
||
return {no, default: MDXContent}
|
||
```
|
||
|
||
The `'program'` format will use import statements to import the runtime (and
|
||
optionally provider) and use an export statement to yield the `MDXContent`
|
||
component.
|
||
|
||
The `'function-body'` format will get the runtime (and optionally provider)
|
||
from `arguments[0]`, rewrite export statements, and use a return statement to
|
||
yield what was exported.
|
||
|
||
</details>
|
||
|
||
* `mdExtensions` (`Array<string>`, default: `['.md', '.markdown', '.mdown',
|
||
'.mkdn', '.mkd', '.mdwn', '.mkdown', '.ron']`)
|
||
— list of markdown extensions, with dot
|
||
affects [§ Integrations][integrations]
|
||
|
||
* `mdxExtensions` (`Array<string>`, default: `['.mdx']`)
|
||
— list of MDX extensions, with dot;
|
||
affects [§ Integrations][integrations]
|
||
|
||
* `pragma` (`string`, default: `'React.createElement'`)
|
||
— pragma for JSX, used in the classic runtime as an identifier for function
|
||
calls: `<x />` to `React.createElement('x')`;
|
||
when changing this, you should also define `pragmaFrag` and
|
||
`pragmaImportSource` too
|
||
|
||
> 👉 **Note**: support for the classic runtime is deprecated and will
|
||
> likely be removed in the next major version.
|
||
|
||
<details><summary>Expand example</summary>
|
||
|
||
If `file` is the contents of `example.mdx` from [§ Use][use], then:
|
||
|
||
```tsx
|
||
compile(file, {
|
||
jsxRuntime: 'classic',
|
||
pragma: 'preact.createElement',
|
||
pragmaFrag: 'preact.Fragment',
|
||
pragmaImportSource: 'preact/compat'
|
||
})
|
||
```
|
||
|
||
…yields this difference:
|
||
|
||
```diff
|
||
-import React from 'react'
|
||
+import preact from 'preact/compat'
|
||
|
||
export function Thing() {
|
||
- return React.createElement(React.Fragment, null, 'World!')
|
||
+ return preact.createElement(preact.Fragment, null, 'World!')
|
||
}
|
||
…
|
||
```
|
||
|
||
</details>
|
||
|
||
* `pragmaFrag` (`string`, default: `'React.Fragment'`)
|
||
— pragma for fragment symbol, used in the classic runtime as an identifier
|
||
for unnamed calls: `<>` to `React.createElement(React.Fragment)`;
|
||
when changing this, you should also define `pragma` and `pragmaImportSource`
|
||
too
|
||
|
||
> 👉 **Note**: support for the classic runtime is deprecated and will
|
||
> likely be removed in the next major version.
|
||
|
||
* `pragmaImportSource` (`string`, default: `'react'`)
|
||
— where to import the identifier of `pragma` from, used in the classic
|
||
runtime;
|
||
to illustrate, when `pragma` is `'a.b'` and `pragmaImportSource` is `'c'`
|
||
the following will be generated: `import a from 'c'` and things such as
|
||
`a.b('h1', {})`;
|
||
when changing this, you should also define `pragma` and `pragmaFrag` too
|
||
|
||
> 👉 **Note**: support for the classic runtime is deprecated and will
|
||
> likely be removed in the next major version.
|
||
|
||
* `providerImportSource` (`string`, optional, example: `'@mdx-js/react'`)
|
||
— place to import a provider from;
|
||
normally it’s used for runtimes that support context (React, Preact), but
|
||
it can be used to inject components into the compiled code;
|
||
the module must export and identifier `useMDXComponents` which is called
|
||
without arguments to get an object of components (see
|
||
[`UseMdxComponents`][api-use-mdx-components])
|
||
|
||
<details><summary>Expand example</summary>
|
||
|
||
If `file` is the contents of `example.mdx` from [§ Use][use], then:
|
||
|
||
```tsx
|
||
compile(file, {providerImportSource: '@mdx-js/react'})
|
||
```
|
||
|
||
…yields this difference:
|
||
|
||
```diff
|
||
import {Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs} from 'react/jsx-runtime'
|
||
+import {useMDXComponents as _provideComponents} from '@mdx-js/react'
|
||
|
||
export function Thing() {
|
||
return _jsx(_Fragment, {children: 'World'})
|
||
}
|
||
|
||
function _createMdxContent(props) {
|
||
const _components = {
|
||
h1: 'h1',
|
||
+ ..._provideComponents(),
|
||
...props.components
|
||
}
|
||
return _jsxs(_components.h1, {children: ['Hello ', _jsx(Thing, {})]})
|
||
}
|
||
|
||
export default function MDXContent(props = {}) {
|
||
- const {wrapper: MDXLayout} = props.components || {}
|
||
+ const {wrapper: MDXLayout} = {
|
||
+ ..._provideComponents(),
|
||
+ ...props.components
|
||
+ }
|
||
|
||
return MDXLayout
|
||
? _jsx(MDXLayout, {...props, children: _jsx(_createMdxContent, {})})
|
||
: _createMdxContent()
|
||
```
|
||
|
||
</details>
|
||
|
||
* `recmaPlugins` ([`PluggableList` from `unified`][unified-pluggable-list],
|
||
optional)
|
||
— list of recma plugins;
|
||
this is a new ecosystem, currently in beta, to transform [esast][] trees
|
||
(JavaScript)
|
||
|
||
<details><summary>Expand example</summary>
|
||
|
||
```tsx
|
||
import recmaMdxIsMdxComponent from 'recma-mdx-is-mdx-component'
|
||
|
||
await compile(file, {recmaPlugins: [recmaMdxIsMdxComponent]})
|
||
```
|
||
|
||
</details>
|
||
|
||
* `rehypePlugins` ([`PluggableList` from `unified`][unified-pluggable-list],
|
||
optional)
|
||
— list of [rehype plugins][rehype-plugins]
|
||
|
||
<details><summary>Expand example</summary>
|
||
|
||
```tsx
|
||
import rehypeKatex from 'rehype-katex' // Render math with KaTeX.
|
||
import remarkMath from 'remark-math' // Support math like `$so$`.
|
||
|
||
await compile(file, {rehypePlugins: [rehypeKatex], remarkPlugins: [remarkMath]})
|
||
|
||
await compile(file, {
|
||
// A plugin with options:
|
||
rehypePlugins: [[rehypeKatex, {strict: true, throwOnError: true}]],
|
||
remarkPlugins: [remarkMath]
|
||
})
|
||
```
|
||
|
||
</details>
|
||
|
||
* `remarkPlugins` ([`PluggableList` from `unified`][unified-pluggable-list],
|
||
optional)
|
||
— list of [remark plugins][remark-plugins]
|
||
|
||
<details><summary>Expand example</summary>
|
||
|
||
```tsx
|
||
import remarkFrontmatter from 'remark-frontmatter' // YAML and such.
|
||
import remarkGfm from 'remark-gfm' // Tables, footnotes, strikethrough, task lists, literal URLs.
|
||
|
||
await compile(file, {remarkPlugins: [remarkGfm]}) // One plugin.
|
||
await compile(file, {remarkPlugins: [[remarkFrontmatter, 'toml']]}) // A plugin with options.
|
||
await compile(file, {remarkPlugins: [remarkGfm, remarkFrontmatter]}) // Two plugins.
|
||
await compile(file, {remarkPlugins: [[remarkGfm, {singleTilde: false}], remarkFrontmatter]}) // Two plugins, first w/ options.
|
||
```
|
||
|
||
</details>
|
||
|
||
* `remarkRehypeOptions` ([`Options` from
|
||
`remark-rehype`][remark-rehype-options], optional)
|
||
— options to pass through to `remark-rehype`;
|
||
the option `allowDangerousHtml` will always be set to `true` and the MDX
|
||
nodes (see [`nodeTypes`][api-node-types]) are passed through;
|
||
In particular, you might want to pass configuration for footnotes if your
|
||
content is not in English
|
||
|
||
<details><summary>Expand example</summary>
|
||
|
||
```tsx
|
||
compile({value: '…'}, {remarkRehypeOptions: {clobberPrefix: 'comment-1'}})
|
||
```
|
||
|
||
</details>
|
||
|
||
* `stylePropertyNameCase` (`'css'` or `'dom`, default: `'dom'`)
|
||
— casing to use for property names in `style` objects;
|
||
CSS casing is for example `background-color` and `-webkit-line-clamp`;
|
||
DOM casing is for example `backgroundColor` and `WebkitLineClamp`;
|
||
for JSX components written in MDX, the author has to be aware of which
|
||
framework they use and write code accordingly;
|
||
for AST nodes generated by this project, this option configures it
|
||
|
||
* `tableCellAlignToStyle` (`boolean`, default: `true`)
|
||
— turn obsolete `align` properties on `td` and `th` into CSS `style`
|
||
properties
|
||
|
||
### `RunOptions`
|
||
|
||
Configuration to run compiled code (TypeScript type).
|
||
|
||
`Fragment`, `jsx`, and `jsxs` are used when the code is compiled in production
|
||
mode (`development: false`).
|
||
`Fragment` and `jsxDEV` are used when compiled in development mode
|
||
(`development: true`).
|
||
`useMDXComponents` is used when the code is compiled with
|
||
`providerImportSource: '#'` (the exact value of this compile option doesn’t
|
||
matter).
|
||
|
||
###### Fields
|
||
|
||
* `Fragment` ([`Fragment`][api-fragment], **required**)
|
||
— symbol to use for fragments
|
||
* `baseUrl` (`URL` or `string`, optional, example: `import.meta.url`)
|
||
— use this URL as `import.meta.url` and resolve `import` and
|
||
`export … from` relative to it;
|
||
this option can also be given at compile time in `CompileOptions`;
|
||
you should pass this (likely at runtime), as you might get runtime errors
|
||
when using `import.meta.url` / `import` / `export … from ` otherwise
|
||
* `jsx` ([`Jsx`][api-jsx], optional)
|
||
— function to generate an element with static children in production mode
|
||
* `jsxDEV` ([`JsxDev`][api-jsx-dev], optional)
|
||
— function to generate an element in development mode
|
||
* `jsxs` ([`Jsx`][api-jsx], optional)
|
||
— function to generate an element with dynamic children in production mode
|
||
* `useMDXComponents` ([`UseMdxComponents`][api-use-mdx-components], optional)
|
||
— function to get components to use
|
||
|
||
###### Examples
|
||
|
||
A `/jsx-runtime` module will expose `Fragment`, `jsx`, and `jsxs`:
|
||
|
||
```tsx
|
||
import * as runtime from 'react/jsx-runtime'
|
||
|
||
const {default: Content} = await evaluate('# hi', {...runtime, baseUrl: import.meta.url, ...otherOptions})
|
||
|
||
```
|
||
|
||
A `/jsx-dev-runtime` module will expose `Fragment` and `jsxDEV`:
|
||
|
||
```tsx
|
||
import * as runtime from 'react/jsx-dev-runtime'
|
||
|
||
const {default: Content} = await evaluate('# hi', {development: true, baseUrl: import.meta.url, ...runtime, ...otherOptions})
|
||
```
|
||
|
||
Our providers will expose `useMDXComponents`:
|
||
|
||
```tsx
|
||
import * as provider from '@mdx-js/react'
|
||
import * as runtime from 'react/jsx-runtime'
|
||
|
||
const {default: Content} = await evaluate('# hi', {...provider, ...runtime, baseUrl: import.meta.url, ...otherOptions})
|
||
```
|
||
|
||
### `UseMdxComponents`
|
||
|
||
Get components (TypeScript type).
|
||
|
||
###### Parameters
|
||
|
||
There are no parameters.
|
||
|
||
###### Returns
|
||
|
||
Components ([`MDXComponents` from `mdx/types.js`][mdx-types-components]).
|
||
|
||
## Types
|
||
|
||
This package is fully typed with [TypeScript][].
|
||
It exports the additional types
|
||
[`CompileOptions`][api-compile-options],
|
||
[`EvaluateOptions`][api-evaluate-options],
|
||
[`Fragment`][api-fragment],
|
||
[`Jsx`][api-jsx],
|
||
[`JsxDev`][api-jsx-dev],
|
||
[`ProcessorOptions`][api-processor-options],
|
||
[`RunOptions`][api-run-options], and
|
||
[`UseMdxComponents`][api-use-mdx-components].
|
||
|
||
For types of evaluated MDX to work, make sure the TypeScript `JSX` namespace is
|
||
typed.
|
||
This is done by installing and using the types of your framework, such as
|
||
[`@types/react`](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react).
|
||
See [§ Types][types] on our website for information.
|
||
|
||
## Architecture
|
||
|
||
To understand what this project does, it’s very important to first understand
|
||
what unified does: please read through the [`unifiedjs/unified`][unified] readme
|
||
(the part until you hit the API section is required reading).
|
||
|
||
`@mdx-js/mdx` is a unified pipeline — wrapped so that most folks don’t need to
|
||
know about unified: [`core.js#L65`][core].
|
||
The processor goes through these steps:
|
||
|
||
1. parse MDX (serialized markdown with embedded JSX, ESM, and expressions)
|
||
to mdast (markdown syntax tree)
|
||
2. transform through remark (markdown ecosystem)
|
||
3. transform mdast to hast (HTML syntax tree)
|
||
4. transform through rehype (HTML ecosystem)
|
||
5. transform hast to esast (JS syntax tree)
|
||
6. do the work needed to get a component
|
||
7. transform through recma (JS ecosystem)
|
||
8. serialize esast as JavaScript
|
||
|
||
The *input* is MDX (serialized markdown with embedded JSX, ESM, and
|
||
expressions).
|
||
The markdown is parsed with [`micromark/micromark`][micromark] and the embedded
|
||
JS with one of its extensions
|
||
[`micromark/micromark-extension-mdxjs`][micromark-extension-mdxjs] (which in
|
||
turn uses [acorn][]).
|
||
Then [`syntax-tree/mdast-util-from-markdown`][mdast-util-from-markdown] and its
|
||
extension [`syntax-tree/mdast-util-mdx`][mdast-util-mdx] are used to turn the
|
||
results from the parser into a syntax tree: [mdast][].
|
||
|
||
Markdown is closest to the source format.
|
||
This is where [remark plugins][remark-plugins] come in.
|
||
Typically, there shouldn’t be much going on here.
|
||
But perhaps you want to support GFM (tables and such) or frontmatter?
|
||
Then you can add a plugin here: `remark-gfm` or `remark-frontmatter`,
|
||
respectively.
|
||
|
||
After markdown, we go to [hast][] (HTML).
|
||
This transformation is done by
|
||
[`syntax-tree/mdast-util-to-hast`][mdast-util-to-hast].
|
||
Wait, why, what is HTML needed?
|
||
Part of the reason is that we care about HTML semantics: we want to know that
|
||
something is an `<a>`, not whether it’s a link with a resource (`[text](url)`)
|
||
or a reference to a defined link definition (`[text][id]\n\n[id]: url`).
|
||
So an HTML AST is *closer* to where we want to go.
|
||
Another reason is that there are many things folks need when they go MDX -> JS,
|
||
markdown -> HTML, or even folks who only process their HTML -> HTML: use cases
|
||
other than MDX.
|
||
By having a single AST in these cases and writing a plugin that works on that
|
||
AST, that plugin can supports *all* these use cases (for example,
|
||
[`rehypejs/rehype-highlight`][rehype-highlight] for syntax highlighting or
|
||
[`rehypejs/rehype-katex`][rehype-katex] for math).
|
||
So, this is where [rehype plugins][rehype-plugins] come in: most of the plugins,
|
||
probably.
|
||
|
||
Then we go to JavaScript: [esast][] (JS; an
|
||
AST which is compatible with estree but looks a bit more like other unist ASTs).
|
||
This transformation is done by
|
||
[`syntax-tree/hast-util-to-estree`][hast-util-to-estree].
|
||
This is a new ecosystem that does not have utilities or plugins yet.
|
||
But it’s where `@mdx-js/mdx` does its thing: where it adds imports/exports,
|
||
where it compiles JSX away into `_jsx()` calls, and where it does the other cool
|
||
things that it provides.
|
||
|
||
Finally, The output is serialized JavaScript.
|
||
That final step is done by [astring][], a
|
||
small and fast JS generator.
|
||
|
||
## Compatibility
|
||
|
||
Projects maintained by the unified collective are compatible with maintained
|
||
versions of Node.js.
|
||
|
||
When we cut a new major release, we drop support for unmaintained versions of
|
||
Node.
|
||
This means we try to keep the current release line, `@mdx-js/mdx@^3`,
|
||
compatible with Node.js 16.
|
||
|
||
## Security
|
||
|
||
See [§ Security][security] on our website for information.
|
||
|
||
## Contribute
|
||
|
||
See [§ Contribute][contribute] on our website for ways to get started.
|
||
See [§ Support][support] for ways to get help.
|
||
|
||
This project has a [code of conduct][coc].
|
||
By interacting with this repository, organization, or community you agree to
|
||
abide by its terms.
|
||
|
||
## License
|
||
|
||
[MIT][] © Compositor and [Vercel][]
|
||
|
||
[build-badge]: https://github.com/mdx-js/mdx/workflows/main/badge.svg
|
||
|
||
[build]: https://github.com/mdx-js/mdx/actions
|
||
|
||
[coverage-badge]: https://img.shields.io/codecov/c/github/mdx-js/mdx/main.svg
|
||
|
||
[coverage]: https://codecov.io/github/mdx-js/mdx
|
||
|
||
[downloads-badge]: https://img.shields.io/npm/dm/@mdx-js/mdx.svg
|
||
|
||
[downloads]: https://www.npmjs.com/package/@mdx-js/mdx
|
||
|
||
[size-badge]: https://img.shields.io/bundlejs/size/@mdx-js/mdx
|
||
|
||
[size]: https://bundlejs.com/?q=@mdx-js/mdx
|
||
|
||
[sponsors-badge]: https://opencollective.com/unified/sponsors/badge.svg
|
||
|
||
[backers-badge]: https://opencollective.com/unified/backers/badge.svg
|
||
|
||
[collective]: https://opencollective.com/unified
|
||
|
||
[chat-badge]: https://img.shields.io/badge/chat-discussions-success.svg
|
||
|
||
[chat]: https://github.com/mdx-js/mdx/discussions
|
||
|
||
[npm]: https://docs.npmjs.com/cli/install
|
||
|
||
[contribute]: https://mdxjs.com/community/contribute/
|
||
|
||
[support]: https://mdxjs.com/community/support/
|
||
|
||
[coc]: https://github.com/mdx-js/.github/blob/main/code-of-conduct.md
|
||
|
||
[mit]: https://github.com/mdx-js/mdx/blob/main/packages/mdx/license
|
||
|
||
[vercel]: https://vercel.com
|
||
|
||
[source-map]: https://github.com/mozilla/source-map
|
||
|
||
[vfile]: https://github.com/vfile/vfile
|
||
|
||
[remark-plugins]: https://github.com/remarkjs/remark/blob/main/doc/plugins.md#list-of-plugins
|
||
|
||
[rehype-plugins]: https://github.com/rehypejs/rehype/blob/main/doc/plugins.md#list-of-plugins
|
||
|
||
[mdx-syntax]: https://mdxjs.com/docs/what-is-mdx/#mdx-syntax
|
||
|
||
[use]: #use
|
||
|
||
[unified]: https://github.com/unifiedjs/unified
|
||
|
||
[core]: https://github.com/mdx-js/mdx/blob/main/packages/mdx/lib/core.js#L65
|
||
|
||
[micromark]: https://github.com/micromark/micromark
|
||
|
||
[acorn]: https://github.com/acornjs/acorn
|
||
|
||
[micromark-extension-mdxjs]: https://github.com/micromark/micromark-extension-mdxjs
|
||
|
||
[mdast-util-from-markdown]: https://github.com/syntax-tree/mdast-util-from-markdown
|
||
|
||
[mdast-util-mdx]: https://github.com/syntax-tree/mdast-util-mdx
|
||
|
||
[mdast]: https://github.com/syntax-tree/mdast
|
||
|
||
[mdast-util-to-hast]: https://github.com/syntax-tree/mdast-util-to-hast
|
||
|
||
[hast]: https://github.com/syntax-tree/hast
|
||
|
||
[hast-util-to-estree]: https://github.com/syntax-tree/hast-util-to-estree
|
||
|
||
[rehype-highlight]: https://github.com/rehypejs/rehype-highlight
|
||
|
||
[rehype-katex]: https://github.com/remarkjs/remark-math/tree/main/packages/rehype-katex
|
||
|
||
[esast]: https://github.com/syntax-tree/esast
|
||
|
||
[astring]: https://github.com/davidbonnet/astring
|
||
|
||
[integrations]: https://mdxjs.com/getting-started/#integrations
|
||
|
||
[using-mdx]: https://mdxjs.com/docs/using-mdx/
|
||
|
||
[esm]: https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c
|
||
|
||
[esmsh]: https://esm.sh
|
||
|
||
[types]: https://mdxjs.com/getting-started/#types
|
||
|
||
[security]: https://mdxjs.com/getting-started/#security
|
||
|
||
[typescript]: https://www.typescriptlang.org
|
||
|
||
[mdx-types-components]: https://github.com/DefinitelyTyped/DefinitelyTyped/blob/HEAD/types/mdx/types.d.ts#L65
|
||
|
||
[mdx-types-module]: https://github.com/DefinitelyTyped/DefinitelyTyped/blob/HEAD/types/mdx/types.d.ts#L101
|
||
|
||
[remark-rehype-options]: https://github.com/remarkjs/remark-rehype#options
|
||
|
||
[unified-pluggable-list]: https://github.com/unifiedjs/unified#pluggablelist
|
||
|
||
[unified-processor]: https://github.com/unifiedjs/unified#processor
|
||
|
||
[vfile-compatible]: https://github.com/vfile/vfile#compatible
|
||
|
||
[api-compile]: #compilefile-options
|
||
|
||
[api-compile-options]: #compileoptions
|
||
|
||
[api-compile-sync]: #compilesyncfile-options
|
||
|
||
[api-create-processor]: #createprocessoroptions
|
||
|
||
[api-evaluate]: #evaluatefile-options
|
||
|
||
[api-evaluate-options]: #evaluateoptions
|
||
|
||
[api-evaluate-sync]: #evaluatesyncfile-options
|
||
|
||
[api-fragment]: #fragment
|
||
|
||
[api-jsx]: #jsx
|
||
|
||
[api-jsx-dev]: #jsxdev
|
||
|
||
[api-node-types]: #nodetypes
|
||
|
||
[api-processor-options]: #processoroptions
|
||
|
||
[api-run]: #runcode-options
|
||
|
||
[api-run-options]: #runoptions
|
||
|
||
[api-run-sync]: #runsynccode-options
|
||
|
||
[api-use-mdx-components]: #usemdxcomponents
|