Skip to navigation

注意: 遇到了一些此处未解释但应该解释的问题吗? 请告诉我们。 请参阅 § 贡献 了解如何提供帮助。

MDX 故障排除

本文介绍了使用 MDX 时可能出现的几个常见问题和错误。 要了解 MDX 格式的工作原理,我们建议你从 § 什么是 MDX 开始。 如何使用 我们的包 记录在他们的自述文件中。 要迁移到最新的 MDX,请参阅 § 从 v1 迁移到 v2

内容

集成 MDX 的问题

ESM

如果你在将 MDX 与不同工具集成时遇到问题,这可能是由于 ESM 造成的: ECMAScript 模块。 它们自 2015 年以来一直在开发中,我们从一开始就在 MDX 文件中支持它们,并且在 MDX 版本 2 中我们完全切换到它们。 许多工具已经支持 ESM。 大多数其他工具正在努力支持它们。 有些仍然需要额外的配置。

有一篇很棒的 Gist by @sindresorhus 详细解释了如何将 ESM 与许多不同的工具结合使用。 如果你在使用 MDX、其他一些工具和 ESM 时遇到问题,你可能会在那里找到你想要的东西。 请仔细阅读。 如果你仍然遇到问题,与 MDX 集成的工具的问题跟踪器可能会提供答案。

如果你在使用不支持 ESM 的工具(例如 Electron)时遇到问题,一种短期解决方案是使用打包器制作 CJS 版本。

展开制作 CJS 包的示例

对于 esbuild,这会将 ESM 包 @mdx-js/mdx 打包为 vendor/mdx.js 中的 CJS:

Shell
npx esbuild @mdx-js/mdx --bundle --platform=node --outfile=vendor/mdx.js

使用 MDX 时遇到的问题

使用 MDX 时出现的问题通常与 我们的包 的 API 以及如何使用它们有关。 请参阅你正在使用的包、函数和选项的文档以获取更多信息和示例。

`options.renderer` is no longer supported

这个错误是由我们的 webpack 加载器 @mdx-js/loader 抛出的。 它在版本 2 中引入以帮助迁移。

renderer 选项允许在每个编译的 MDX 文件之前注入任意文本。 这通常用于支持 React 以外的框架,例如 Preact。 我们现在有 jsxImportSource 等选项,并且可以使用 recmaPlugins 添加任意 JavaScript。 由于版本 2 使用基于 AST 的方法,因此支持 renderer 不再可行,因此被删除。

如何支持 Preact 请参见 ¶ 入门中的 Preact。 请参阅 ¶ 扩展 MDX 中的创建插件 了解如何创建插件。

Incorrect `format: 'detect'`

Unexpected `format: 'detect'`

MDX 2 中的完整错误消息如下:

Incorrect `format: 'detect'`: `createProcessor` can support either `md` or `mdx`; it does not support detecting the format

MDX 3 中的完整错误消息是:

Unexpected `format: 'detect'`, which is not supported by `createProcessor`, expected `'mdx'` or `'md'`

这个错误是由我们的核心编译器 @mdx-js/mdx 抛出的。 它是在版本 2 中引入 format 选项时引入的。

format 选项与 'detect' 配置时,允许推断文件是 MDX 还是普通 Markdown。 根据该信息,插件的配置不同,并且具有不同的选项。 这对于 createProcessorunified 来说是不可能的。

要检测传递的文件的格式,请使用 @mdx-js/mdx 中的 compile 或其中一个集成。

Missing `pragma` in classic runtime with `pragmaImportSource`

这个错误是由我们的核心编译器 @mdx-js/mdx 抛出的。 它是在版本 2 中引入的,当时引入了 jsxRuntimepragmapragmaImportSource 选项。

jsxRuntime 配置了 'classic'(默认为 'automatic'),定义了 pragmaImportSource(默认为 'react'),但 pragma 定义为假值(默认为 React.createElement)时,会抛出此错误。

如果你使用经典运行时,则必须定义 pragma

Unexpected deprecated option `jsxRuntime: 'classic'`, `pragma`, `pragmaFrag`, or `pragmaImportSource`

这是一个警告。 这不是一个错误。 你可以继续使用这些选项,但预计它们将来会被删除。

目前所有主要框架都支持自动 JSX 运行时。 从 MDX 的角度来看,经典运行时存在一些潜在的问题。

因此,我们强烈建议使用自动 JSX 运行时,并正在考虑删除对经典 JSX 运行时的支持。

Expected `Fragment` given to `evaluate`

Expected `jsx` given to `evaluate`

Expected `jsxs` given to `evaluate`

这些错误是由我们的核心编译器 @mdx-js/mdx 引发的。 它们是在版本 2 中引入 evaluate(和 evaluateSync)时引入的。

evaluate 支持 React 等框架。 但这些框架必须支持公开这三个导出的自动 JSX 运行时。 如果你收到此错误,则意味着 a) 框架不支持自动 JSX 运行时,或者 b) 你没有将它们正确地传递给 evaluate

有关如何传递这些值的示例,请参阅 evaluate@mdx-js/mdx

Unexpected missing `options.baseUrl` needed…

MDX 中的完整错误消息如下:

Unexpected missing `options.baseUrl` needed to support `export … from`, `import`, or `import.meta.url` when generating `function-body`

当 MDX 运行专门使用 evaluate 编译的 MDX 或使用 outputFormat: 'function-body' 选项稍后在某处进行评估,并且使用 import.meta.urlimportexport … from 时,会引发此错误。 这些 JavaScript 功能依赖于运行的特定 URL,在运行函数体时该 URL 不可用或不正确。 要解决此问题,请传递 baseUrl 选项。 可能设置为 import.meta.url(或 window.location.href)。

写入 MDX 时出现问题

编写 MDX 时出现的问题通常与如何结合 JS(X) 和 markdown 有关。 这是两种语言的奇怪混合: markdown 是 空格敏感forgiving(你输入的内容可能不完全有效,但不会崩溃),而 JavaScript 是 空格不敏感unforgiving(它确实会因拼写错误而崩溃)。

错误通常分为以下三类:

  • 没有转义 <{ — 如果你将这些 (\<, \{) 表示为纯文本而不是 JS(X),请转义它们
  • 不正确的交错 — 参见 ¶ 什么是 MDX 中的交织 中的规则
  • JavaScript 损坏 — 确保你编写的 JavaScript 有效

Could not parse import/exports with acorn: $error

此错误是由我们的 MDX 解析器引发的。 它是在版本 2 中引入的。 当在行首找到关键字 importexport 但后面没有有效的 JavaScript 时,就会发生这种情况。 一个例子是:

import 1/1

此错误的原因是解析器需要 JavaScript 导入或导出语句。 如果你想要“导入”或“导出”一词,请确保它不在段落的开头。 如果你确实需要导入或导出语句,请确保它是有效的 JavaScript。

Unexpected `$type` in code: only import/exports are supported

此错误是由我们的 MDX 解析器引发的。 它是在版本 2 中引入的。 当在 importexport 语句之后发现更多 JavaScript 时,就会发生这种情况。 一个例子是:

export const a = 1
const b = 2

出现这个错误的原因是我们只允许 importexport 定义数据。 如果你想定义变量或函数,请将其导出。

Unexpected end of file in expression, expected a corresponding closing brace for `{`

此错误是由我们的 MDX 解析器引发的。 它是在版本 2 中引入的。 当左大括号后面没有右大括号时,就会发生这种情况。 一个例子是:

a { b

此错误的原因是解析器需要另一个大括号。 如果你只想要大括号而不是表达式,请转义它: \{。 如果你确实需要表达式,请确保用右大括号 } 将其关闭。 如果某处有右大括号,请确保每个大括号都在自己的行上,左大括号之前没有文本,右大括号之后没有文本,或者大括号之间没有空行。

Unexpected lazy line in expression in container

此错误是由我们的 MDX 解析器引发的。 它是在版本 3 中引入的。 当具有惰性行的容器与表达式组合时会发生这种情况,示例如下:

* {1 +
2}

> {1 +
2}

出现此错误的原因是解析器可能指向一个错误。 明确列出你的列表项并引用块:

* {1 +
  2}

> {1 +
> 2}

Could not parse expression with acorn: $error

此错误是由我们的 MDX 解析器引发的。 它是在版本 2 中引入的。 当存在匹配的大括号时就会发生这种情况,当将其中的内容解释为 JavaScript 时,会导致语法错误。 一个例子是:

a {const b = 'c'} d

另一个例子:

a {!} d

出现此错误的原因是解析器需要 JavaScript 表达式。 如果你只想要大括号而不是表达式,请转义开头: \{。 如果你确实需要表达式,请确保它是有效的 JavaScript 并且它是一个表达式。 这意味着语句(例如 ifelsefor 循环)不起作用。 如果你需要复杂的逻辑,你可以将语句和整个程序封装到 IIFE 中,或者将其移至其他文件,从那里导出,然后将其导入到 MDX 中。

Could not parse expression with acorn: Unexpected content after expression

此错误是由我们的 MDX 解析器引发的。 它是在版本 2 中引入的。 当有匹配的大括号,并且其中有有效的 JavaScript,但 JavaScript 太多时,就会发生这种情况。 一个例子是:

a {'b' 'c'} d

出现此错误的原因是解析器期望单个 JavaScript 表达式产生一个值。 如果你只想要大括号而不是表达式,请转义开头: \{。 如果你确实需要表达式,请确保它产生单个值。

Unexpected extra content in spread: only a single spread is supported

此错误是由我们的 MDX 解析器引发的。 它是在版本 2 中引入的。 当 JSX 标记中有多个值时,就会发生这种情况。 一个例子是:

<div {...a, ...b} />

出现此错误的原因是 JSX 一次只允许传播单个值:

<div {...a} {...b} />

Unexpected `$type` in code: only spread elements are supported

Unexpected empty expression

这些错误是由我们的 MDX 解析器引发的。 它们是在版本 2 中引入的。 当牙套中使用除牙套之外的其他东西时,就会发生这种情况。 一个例子是:

<div {values} {/* comment */} {} />

出现此错误的原因是 JSX 只允许传播值:

<div {...a} />

Unexpected end of file $at, expected $expect

Unexpected character $at, expected $expect

这些错误是由我们的 MDX 解析器引发的。 它们是在 MDX 版本 2 中引入的。 当在 JSX 标记中发现意外情况时,就会发生这种情况。 一些例子是:

<
<.>
</
</.>
<a
<a?>
<a:
<a:+>
<a.
<a./>
<a b
<a b!>
<a b:
<a b:1>
<a b=
<a b=>
<a b="
<a b='
<a b={
<a/
<a/->

出现这些错误的原因是 JSX 有非常严格的语法并期望标签有效。 根据预期的不同,有不同的解决方案。 请仔细阅读错误消息,因为它指出了问题发生的位置以及预期的情况。

Unexpected closing slash `/` in tag, expected an open tag first

此错误是由我们的 MDX 解析器引发的。 它是在版本 2 中引入的。 当找到结束标签但没有打开标签时会发生这种情况。 一个例子是:


</div>

出现此错误的原因是只有开放标签才能关闭。 你可能忘记了某个地方的开始标签。

Unexpected lazy line in container, expected line to be…

此错误是由我们的 MDX 解析器引发的。 它是在版本 3 中引入的。 当具有惰性行的容器与 JSX 结合时,就会发生这种情况。 一个例子是:

* <x
y />

> <x
y />

出现此错误的原因是解析器可能指向一个错误。 明确列出你的列表项并引用块:

* <x
  y />

> <x
> y />

Unexpected attribute in closing tag, expected the end of the tag

此错误是由我们的 MDX 解析器引发的。 它是在版本 2 中引入的。 当属性放置在结束标记上时会发生这种情况。 一个例子是:

<h1>Text</h1 id="text">

出现此错误的原因是只有开放标签才能具有属性。 将这些属性移动到相应的开始标记。

Unexpected self-closing slash `/` in closing tag, expected the end of the tag

此错误是由我们的 MDX 解析器引发的。 它是在版本 2 中引入的。 当关闭标签也被标记为自关闭时,就会发生这种情况。 一个例子是:

<h1>Text</h1/>

出现此错误的原因是只有开始标签才能标记为自关闭。 删除标签名称后面和 > 之前的斜杠。

Unexpected closing tag `</$tag>`, expected corresponding closing tag for `<$tag>` ($at)

此错误是由我们的 MDX 解析器引发的。 它是在版本 2 中引入的。 当发现结束标记与预期的开始标记不匹配时,就会发生这种情况。 一个例子是:

<a>Text</b>

出现此错误的原因是 JSX 中的标签必须匹配。 你可能忘记正确打开或关闭两者之一。

Cannot close `$type` ($at): a different token (`$type`, $at) is open

Cannot close document, a token (`$type`, $at) is still open

此错误是由我们的 MDX 解析器引发的。 它是在版本 2 中引入的。 当 markdown 和 JSX 未正确交错时,通常会发生这种情况。 一个例子是:

> <div>

出现此错误的原因是 Markdown 构造在仍有标签打开时结束。 参见 ¶ 什么是 MDX 中的交织 的规则

MDX 中文网 - 粤ICP备13048890号