不能要求 gatsby-plugin-mdx 的评论和重新炒作插件
Can't require remark and rehype plugins for gatsby-plugin-mdx
我试图按照 documentation 为 gatsby-plugin-mdx 包含 rehype 插件。具体来说,我试图使用 rehype-slug
插件。我用 npm 安装了打包并将我的 gatsby.config.js
文件设置为
module.exports = {
siteMetadata: {
siteUrl: "https://www.yourdomain.tld",
title: "test Website",
},
plugins: [
{
resolve: "gatsby-plugin-mdx",
options:{
rehypePlugins: [
require("rehype-slug")
]
}
}
],
};
但是在 运行 gatsby develop
我遇到了以下错误:
Error: [ERR_REQUIRE_ESM]: Must use import to load ES Module: C:\Users\User\Documents\test-site\node_modules\rehype-slug\index.js require() of ES modules is not supported.
我在尝试使用 remark-math
和 rehype-katex
插件时遇到了类似的问题。我使用的是 Gatsby CLI 3.13.0 版。即使使用全新的网站,问题仍然存在。对此问题的任何帮助将不胜感激。
不确定它是否有效,但是,您是否尝试过类似的东西,而不是使用 ES 模块的 require:
import slug from 'rehype-slug'
module.exports = {
siteMetadata: {
siteUrl: "https://www.yourdomain.tld",
title: "test Website",
},
plugins: [
{
resolve: "gatsby-plugin-mdx",
options:{
rehypePlugins: [
slug
]
}
}
],
};
基于:https://github.com/rehypejs/rehype-slug
或者直接在rehypePlugins
里面导入动态导入。
我做了一些研究,发现不支持动态导入,因为您无法访问回调中的值,所以等待导入不是解决方案,也不是使用 ES module.
但是,可以在此 GitHub discussion:
中找到与您完全相同的用例的最终解决方案(或至少是临时工作的解决方案)
Update: I got the update to rehype-slug@5.0.0
in my gatsby-config.js
working by installing esm
and patch-package
and:
Modifying the gatsby-config.js
as follows (to allow require()
with the pure ES Modules)
require = require('esm')(module);
module.exports = {
plugins: [
{
resolve: `gatsby-plugin-mdx`,
options: {
rehypePlugins: [
require('rehype-slug').default,
Try running the Gatsby dev server and see what breaks. It will throw an error either like this:
Error: Must use import to load ES Module: /Users/k/p/project/node_modules/rehype-slug/index.js
require() of ES modules is not supported.
require() of /Users/k/p/project/node_modules/rehype-slug/index.js from /Users/k/p/project/gatsby-config.js is an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which defines all .js files in that package scope as ES modules.
Instead rename index.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from /Users/k/p/project/node_modules/rehype-slug/package.json.
...or like this:
Error: /Users/k/p/project/gatsby-config.js:1
Error: Must use import to load ES Module: /Users/k/p/project/node_modules/rehype-slug/index.js
Make a note of the location of the pure ES Modules package so that you can locate the package.json
file corresponding to the pure ESM package and manually remove the line with "type": "module",
like this:
- "type": "module",
Run yarn patch-package <pkg name> --exclude '^$'
, which will record the changes that you have made in the package.json
file (to be reapplied by patch-package
every time that you run yarn
or npm install
). Examples:
# For a top-level dependency
yarn patch-package rehype-slug --exclude '^$'
# For a transitive dependency
yarn patch-package rehype-slug/unist-util-visit --exclude '^$'
Run the Gatsby dev server again, and repeat step 3 and 4 for every pure ESM package.
At that point, I could start the Gatsby dev server with the new pure ESM dependency versions.
cc @Ir1d @kimbaudi @wardpeet @LekoArts
Caveat: In my specific case, I needed to also patch one of the dependencies (hast-util-heading-rank
) because I was getting an undefined node.tagName
, but I think this is unrelated to this problem - probably related to a different issue.
全部归功于所涉及的魔术师
中还有一个更简单优雅的解决方案
在根文件夹中创建 require-esm.js
(与 package.json 相同的位置):
// Source:
const esm = require('esm')
const fs = require('fs')
const Module = require('module')
// Node: bypass [ERR_REQUIRE_ESM]
const orig = Module._extensions['.js']
Module._extensions['.js'] = function (module, filename) {
try {
return orig(module, filename)
} catch (e) {
const content = fs.readFileSync(filename, 'utf8')
module._compile(content, filename)
}
}
const _esmRequire = esm(module, {
cjs: true,
mode: 'all',
})
// don't pollute Module
Module._extensions['.js'] = orig
module.exports = function esmRequire(id) {
return _esmRequire(id).default
}
然后像这样在 gatsby-config.js
中使用它:
require.esm = require('./require-esm')
module.exports = {
.......
{
resolve: `gatsby-plugin-mdx`,
options: {
extensions: ['.mdx', '.md'],
rehypePlugins: [
// Generate heading ids for rehype-autolink-headings
[require.esm('rehype-slug')],
// To pass options, use a 2-element array with the
// configuration in an object in the second element
[require.esm('rehype-autolink-headings'), { behavior: "wrap" }],
],
}
},
.......
}
更新
经过一些测试后,我将上面的代码简化为几行。它在我的设置中仍然有效。
像这样在 gatsby-config.js
中使用 require.esm(...)
:
const requireEsm = require('esm')(module)
require.esm = id => requireEsm(id).default
module.exports = {
.......
rehypePlugins: [
// Generate heading ids for rehype-autolink-headings
[require.esm('rehype-slug')],
.......
}
我试图按照 documentation 为 gatsby-plugin-mdx 包含 rehype 插件。具体来说,我试图使用 rehype-slug
插件。我用 npm 安装了打包并将我的 gatsby.config.js
文件设置为
module.exports = {
siteMetadata: {
siteUrl: "https://www.yourdomain.tld",
title: "test Website",
},
plugins: [
{
resolve: "gatsby-plugin-mdx",
options:{
rehypePlugins: [
require("rehype-slug")
]
}
}
],
};
gatsby develop
我遇到了以下错误:
Error: [ERR_REQUIRE_ESM]: Must use import to load ES Module: C:\Users\User\Documents\test-site\node_modules\rehype-slug\index.js require() of ES modules is not supported.
我在尝试使用 remark-math
和 rehype-katex
插件时遇到了类似的问题。我使用的是 Gatsby CLI 3.13.0 版。即使使用全新的网站,问题仍然存在。对此问题的任何帮助将不胜感激。
不确定它是否有效,但是,您是否尝试过类似的东西,而不是使用 ES 模块的 require:
import slug from 'rehype-slug'
module.exports = {
siteMetadata: {
siteUrl: "https://www.yourdomain.tld",
title: "test Website",
},
plugins: [
{
resolve: "gatsby-plugin-mdx",
options:{
rehypePlugins: [
slug
]
}
}
],
};
基于:https://github.com/rehypejs/rehype-slug
或者直接在rehypePlugins
里面导入动态导入。
我做了一些研究,发现不支持动态导入,因为您无法访问回调中的值,所以等待导入不是解决方案,也不是使用 ES module.
但是,可以在此 GitHub discussion:
中找到与您完全相同的用例的最终解决方案(或至少是临时工作的解决方案)Update: I got the update to
rehype-slug@5.0.0
in mygatsby-config.js
working by installingesm
andpatch-package
and:
Modifying the
gatsby-config.js
as follows (to allowrequire()
with the pure ES Modules)require = require('esm')(module); module.exports = { plugins: [ { resolve: `gatsby-plugin-mdx`, options: { rehypePlugins: [ require('rehype-slug').default,
Try running the Gatsby dev server and see what breaks. It will throw an error either like this:
Error: Must use import to load ES Module: /Users/k/p/project/node_modules/rehype-slug/index.js require() of ES modules is not supported. require() of /Users/k/p/project/node_modules/rehype-slug/index.js from /Users/k/p/project/gatsby-config.js is an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which defines all .js files in that package scope as ES modules. Instead rename index.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from /Users/k/p/project/node_modules/rehype-slug/package.json.
...or like this:
Error: /Users/k/p/project/gatsby-config.js:1 Error: Must use import to load ES Module: /Users/k/p/project/node_modules/rehype-slug/index.js
Make a note of the location of the pure ES Modules package so that you can locate the
package.json
file corresponding to the pure ESM package and manually remove the line with"type": "module",
like this:- "type": "module",
Run
yarn patch-package <pkg name> --exclude '^$'
, which will record the changes that you have made in thepackage.json
file (to be reapplied bypatch-package
every time that you runyarn
ornpm install
). Examples:# For a top-level dependency yarn patch-package rehype-slug --exclude '^$' # For a transitive dependency yarn patch-package rehype-slug/unist-util-visit --exclude '^$'
Run the Gatsby dev server again, and repeat step 3 and 4 for every pure ESM package.
At that point, I could start the Gatsby dev server with the new pure ESM dependency versions.
cc @Ir1d @kimbaudi @wardpeet @LekoArts
Caveat: In my specific case, I needed to also patch one of the dependencies (
hast-util-heading-rank
) because I was getting an undefinednode.tagName
, but I think this is unrelated to this problem - probably related to a different issue.
全部归功于所涉及的魔术师
在根文件夹中创建 require-esm.js
(与 package.json 相同的位置):
// Source:
const esm = require('esm')
const fs = require('fs')
const Module = require('module')
// Node: bypass [ERR_REQUIRE_ESM]
const orig = Module._extensions['.js']
Module._extensions['.js'] = function (module, filename) {
try {
return orig(module, filename)
} catch (e) {
const content = fs.readFileSync(filename, 'utf8')
module._compile(content, filename)
}
}
const _esmRequire = esm(module, {
cjs: true,
mode: 'all',
})
// don't pollute Module
Module._extensions['.js'] = orig
module.exports = function esmRequire(id) {
return _esmRequire(id).default
}
然后像这样在 gatsby-config.js
中使用它:
require.esm = require('./require-esm')
module.exports = {
.......
{
resolve: `gatsby-plugin-mdx`,
options: {
extensions: ['.mdx', '.md'],
rehypePlugins: [
// Generate heading ids for rehype-autolink-headings
[require.esm('rehype-slug')],
// To pass options, use a 2-element array with the
// configuration in an object in the second element
[require.esm('rehype-autolink-headings'), { behavior: "wrap" }],
],
}
},
.......
}
更新
经过一些测试后,我将上面的代码简化为几行。它在我的设置中仍然有效。
像这样在 gatsby-config.js
中使用 require.esm(...)
:
const requireEsm = require('esm')(module)
require.esm = id => requireEsm(id).default
module.exports = {
.......
rehypePlugins: [
// Generate heading ids for rehype-autolink-headings
[require.esm('rehype-slug')],
.......
}