'Can't require remark and rehype plugins for gatsby-plugin-mdx
I was trying to follow the documentation on including rehype plugins for gatsby-plugin-mdx. Specifically I was trying to use the rehype-slug plugin. I installed the packaged with npm and set my gatsby.config.js file to
module.exports = {
siteMetadata: {
siteUrl: "https://www.yourdomain.tld",
title: "test Website",
},
plugins: [
{
resolve: "gatsby-plugin-mdx",
options:{
rehypePlugins: [
require("rehype-slug")
]
}
}
],
};
gatsby develop I encouter the following error:
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.
I encouter similar problems when trying to use the remark-math and rehype-katex plugins. I'm using version 3.13.0 of the Gatsby CLI. The problem persists even with a completely new website. Any help with this issue would be much appreciated.
Solution 1:[1]
There is a simpler and more elegant solution in the same GitHub discussion
Create require-esm.js in the root folder (same place as package.json):
// Source: https://stackoverflow.com/a/71344589/2078908
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
}
Then use it in gatsby-config.js like this:
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" }],
],
}
},
.......
}
Update
After some testing I've simplified code above to couple lines. It still works in my setup.
Use require.esm(...) in gatsby-config.js like this:
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')],
.......
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
