Skip to navigation

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

¥Note: Had trouble with something that wasn’t explained here but should be? Please let us know. See § Contribute for how to help.

MDX 故障排除

¥Troubleshooting MDX

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

¥This article goes through several common problems and errors that might occur when using MDX. To understand how the MDX format works, we recommend that you start with § What is MDX. How to use our packages is documented in their readmes. To migrate to the latest MDX, see § Migrating from v1 to v2.

内容

¥Contents

集成 MDX 的问题

¥Problems integrating MDX

ESM

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

¥If you’re having problems integrating MDX with different tools, that’s likely due to ESM: ECMAScript modules. They’ve been in the works since 2015, we’ve supported them in MDX files from the start, and in MDX version 2 we completely switched to them. Many tools support ESM already. Most other tools are working hard to support them. Some still require extra configuration.

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

¥There’s a great Gist by @sindresorhus which explains in detail how to use ESM with many different tools. If you’re having trouble with MDX, some other tool, and ESM, you’ll likely find what you’re looking for there. Please give it a thorough read. If you’re still having problems, the issue tracker of the tools you’re integrating MDX with might provide the answer.

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

¥If you’re having trouble with tools that don’t support ESM, such as Electron, one short-term solution is to use a bundler to make a CJS version.

Expand example of making a CJS bundle

With esbuild, this bundles the ESM package @mdx-js/mdx as CJS in vendor/mdx.js:

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

使用 MDX 时遇到的问题

¥Problems using MDX

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

¥Problems that occur when using MDX typically relate to the APIs of our packages and how to use them. Please see the documentation of the packages, functions, and options you are using for more info and examples.

``options.renderer is no longer supported

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

¥This error is thrown by @mdx-js/loader, our webpack loader. It was introduced in version 2 to help with migration.

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

¥The renderer option allowed arbitrary text to be injected before each compiled MDX file. This was typically used to support frameworks other than React such as Preact. We now have options such as jsxImportSource for that and arbitrary JavaScript can be added with recmaPlugins. Because version 2 uses an AST based approach, it is no longer feasible to support a renderer, so it was removed.

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

¥Please see ¶ Preact in § Getting started for how to support Preact. See ¶ Creating plugins in § Extending MDX for how to create plugins.

Incorrect format: 'detect'``

Unexpected format: 'detect'``

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

¥The full error message in MDX 2 is as follows:

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

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

¥The full error message in MDX 3 is:

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

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

¥This error is thrown by @mdx-js/mdx, our core compiler. It was introduced in version 2 when the format option was introduced.

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

¥The format option, when configured with 'detect', allows inferring whether a file is MDX or plain markdown. Based on that information, plugins are configured differently, and with different options. This is impossible with createProcessor and unified.

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

¥To detect the format of passed files, please either use compile from @mdx-js/mdx or one of the integrations.

Missing pragmain classic runtime withpragmaImportSource``

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

¥This error is thrown by @mdx-js/mdx, our core compiler. It was introduced in version 2 when the jsxRuntime, pragma, and pragmaImportSource options were introduced.

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

¥This error is thrown when jsxRuntime is configured with 'classic' (the default is 'automatic'), pragmaImportSource is defined (the default is 'react'), but pragma is defined as a falsey value (the default is React.createElement).

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

¥If you are using the classic runtime, you have to define a pragma.

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

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

¥This is a warning. It is not an error. You can keep on using these options, but expect them to be removed in the future.

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

¥All major frameworks currently support the automatic JSX runtime. The classic runtime, from MDX perspective, comes with several potential problems.

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

¥Because of that, we strongly recommend using an automatic JSX runtime and are considering removing support for the classic JSX runtime.

Expected Fragmentgiven toevaluate``

Expected jsxgiven toevaluate``

Expected jsxsgiven toevaluate``

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

¥These errors are thrown by @mdx-js/mdx, our core compiler. They were introduced in version 2 when evaluate (and evaluateSync) were introduced.

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

¥evaluate supports React and other frameworks. But these frameworks must support an automatic JSX runtime that exposes these three exports. If you’re getting this error, that means that either a) the framework does not support the automatic JSX runtime, or b) that you’re not passing them correctly to evaluate.

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

¥Please see evaluate in @mdx-js/mdx for examples on how to pass these values.

Unexpected missing options.baseUrl needed…

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

¥The full error message in MDX is as follows:

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)。

¥This error is thrown when MDX runs that is specifically compiled with evaluate, or with the outputFormat: 'function-body' option to evluate somewhere later, and import.meta.url, import, or export … from is used. These JavaScript features depend on a particular URL to run from, which is not available or not correct when running a function body. To solve this, pass a baseUrl option. Likely set to import.meta.url (or window.location.href).

写入 MDX 时出现问题

¥Problems writing MDX

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

¥Problems that occur when writing MDX typically have relate to how to combine JS(X) and markdown. It’s an odd mix of two languages: markdown is whitespace sensitive and forgiving (what you type may not exactly work but it won’t crash) whereas JavaScript is whitespace insensitive and unforgiving (it does crash on typos).

错误通常分为以下三类:

¥Errors typically fall in these three categories:

  • 不转义 <\{ — 如果你将它们表示为纯文本而不是 JS(X),请转义这些 (<, {`)

    ¥**Not escaping < and \{** — Escape these (<, {`) if you mean them as plain text instead of JS(X)

  • 不正确的交错 — 请参阅 ¶ 什么是 MDX 中的交织 中的规则

    ¥Incorrect interleaving — See the rules in ¶ Interleaving in § What is MDX?

  • 损坏的 JavaScript — 确保你编写的 JavaScript 有效

    ¥Broken JavaScript — Make sure the JavaScript you write is valid

Could not parse import/exports with acorn: $error

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

¥This error is thrown by our MDX parser. It was introduced in version 2. It occurs when the keywords import or export are found at the start of a line but they are not followed by valid JavaScript. An example is:

import 1/1

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

¥The reason for this error is that the parser is expecting a JavaScript import or export statement. If you want the word import or export, make sure it’s not at the start of a paragraph. If you do want an import or export statement, please make sure that it’s valid JavaScript.

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

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

¥This error is thrown by our MDX parser. It was introduced in version 2. It occurs when, after an import or export statement, more JavaScript is found. An example is:

export const a = 1
const b = 2

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

¥The reason for this error is that we only allow import and export to define data. If you want to define a variable or function, please export it.

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

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

¥This error is thrown by our MDX parser. It was introduced in version 2. It occurs when there is an opening curly brace not followed by a closing brace. An example is:

a { b

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

¥The reason for this error is that the parser is expecting another curly brace. If you just want a brace but not an expression, escape it: \{. If you do want an expression, please make sure to close it with a closing brace }. If there is a closing brace somewhere, make sure that the braces are each on their own lines with no text before the opening brace and no text after the closing brace, or that there are no blank lines between the braces.

Unexpected lazy line in expression in container

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

¥This error is thrown by our MDX parser. It was introduced in version 3. It occurs when containers with lazy lines are combined with expressions An example is:


* {1 +
2}

> {1 +
2}

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

¥The reason for this error is that the parser it likely points to a bug. Be explicit with your list items and block quotes:


* {1 +
  2}

> {1 +
> 2}

Could not parse expression with acorn: $error

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

¥This error is thrown by our MDX parser. It was introduced in version 2. It occurs when there are matching curly braces that, when interpreting what’s inside them as JavaScript, results in a syntax error. An example is:

a {const b = 'c'} d

另一个例子:

¥Another example:

a {!} d

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

¥The reason for this error is that the parser is expecting a JavaScript expression. If you just want braces instead of an expression, escape the opening: \{. If you do want an expression, make sure that it’s valid JavaScript and that it is an expression. That means statements (such as if and else and for loops) do not work. If you need complex logic, you can wrap statements and whole programs into an IIFE, or move it out to a different file, export it from there, and import it in MDX.

Could not parse expression with acorn: Unexpected content after expression

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

¥This error is thrown by our MDX parser. It was introduced in version 2. It occurs when there are matching curly braces that, and valid JavaScript is inside them, but there’s too much JavaScript. An example is:

a {'b' 'c'} d

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

¥The reason for this error is that the parser is expecting a single JavaScript expression yielding one value. If you just want braces instead of an expression, escape the opening: \{. If you do want an expression, make sure that it yields a single value.

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

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

¥This error is thrown by our MDX parser. It was introduced in version 2. It occurs when there are multiple values spread into a JSX tag. An example is:

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

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

¥The reason for this error is that JSX only allows spreading a single value at a time:

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

Unexpected $type in code: only spread elements are supported

Unexpected empty expression

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

¥These errors are thrown by our MDX parser. They were introduced in version 2. They occur when something other than a spread is used in braces. An example is:

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

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

¥The reason for this error is that JSX only allows spreading values:

<div {...a} />

Unexpected end of file $at, expected $expect

Unexpected character $at, expected $expect

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

¥These errors are thrown by our MDX parser. They were introduced in MDX version 2. They occur when something unexpected was found in a JSX tag. Some examples are:

<
<.>
</
</.>
<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 有非常严格的语法并期望标签有效。根据预期的不同,有不同的解决方案。请仔细阅读错误消息,因为它指出了问题发生的位置以及预期的情况。

¥The reason for these errors is that JSX has a very strict grammar and expects tags to be valid. There are different solutions depending on what was expected. Please read the error message carefully as it indicates where the problem occurred and what was expected instead.

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

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

¥This error is thrown by our MDX parser. It was introduced in version 2. It occurs when a closing tag is found but there are no open tags. An example is:


</div>

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

¥The reason for this error is that only open tags can be closed. You probably forgot an opening tag somewhere.

Unexpected lazy line in container, expected line to be…

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

¥This error is thrown by our MDX parser. It was introduced in version 3. It occurs when containers with lazy lines are combined with JSX. An example is:


* <x
y />

> <x
y />

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

¥The reason for this error is that the parser it likely points to a bug. Be explicit with your list items and block quotes:


* <x
  y />

> <x
> y />

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

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

¥This error is thrown by our MDX parser. It was introduced in version 2. It occurs when attributes are placed on closing tags. An example is:

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

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

¥The reason for this error is that only open tags can have attributes. Move these attributes to the corresponding opening tag.

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

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

¥This error is thrown by our MDX parser. It was introduced in version 2. It occurs when a closing tag is also marked as self-closing. An example is:

<h1>Text</h1/>

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

¥The reason for this error is that only opening tags can be marked as self-closing. Remove the slash after the tag name and before >.

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

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

¥This error is thrown by our MDX parser. It was introduced in version 2. It occurs when a closing tag is seen that does not match the expected opening tag. An example is:

<a>Text</b>

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

¥The reason for this error is that tags must match in JSX. You likely forgot to open or close one of the two correctly.

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 未正确交错时,通常会发生这种情况。一个例子是:

¥This error is thrown by our MDX parser. It was introduced in version 2. It typically occurs when markdown and JSX are not interleaved correctly. An example is:

> <div>

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

¥The reason for this error is that a markdown construct ends while there are still tags open. See the rules on ¶ Interleaving in § What is MDX?

MDX 中文网 - 粤ICP备13048890号