簡體   English   中英

不能要求 gatsby-plugin-mdx 的評論和重新炒作插件

[英]Can't require remark and rehype plugins for gatsby-plugin-mdx

我試圖按照有關包括 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-mathrehype-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 模塊

但是,可以在此GitHub 討論中找到與您完全相同的用例的最終解決方案(或至少是臨時工作的解決方案):

更新:我通過安裝esmpatch-package在我的gatsby-config.js中獲得了rehype-slug@5.0.0的更新,並且:

  1. 修改gatsby-config.js如下(允許require()與純 ES 模塊)

     require = require('esm')(module); module.exports = { plugins: [ { resolve: `gatsby-plugin-mdx`, options: { rehypePlugins: [ require('rehype-slug').default,
  2. 嘗試運行 Gatsby 開發服務器,看看有什么問題。 它會像這樣拋出錯誤:

     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.

    ...或者像這樣:

     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
  3. 記下pure ES Modules package的位置,這樣就可以定位到pure ESM package對應的package.json文件,手動去掉"type": "module",像這樣:

     - "type": "module",
  4. 運行yarn patch-package <pkg name> --exclude '^$' ,這將記錄您在package.json文件中所做的更改(每次運行yarnnpm install時都會由patch-package重新應用)。 例子:

     # For a top-level dependency yarn patch-package rehype-slug --exclude '^$' # For a transitive dependency yarn patch-package rehype-slug/unist-util-visit --exclude '^$'
  5. 再次運行 Gatsby 開發服務器,並為每個純 ESM package 重復步驟 3 和 4。

那時,我可以使用新的純 ESM 依賴版本啟動 Gatsby 開發服務器。

cc @Ir1d @kimbaudi @wardpeet @LekoArts

警告:在我的具體情況下,我還需要修補其中一個依賴項 ( hast-util-heading-rank ),因為我得到了一個未定義的node.tagName ,但我認為這與這個問題無關——可能與另一個問題有關問題。

所有學分都歸功於所涉及的魔術師

GitHub討論中有更簡單優雅的解決方案

在根文件夾中創建require-esm.js (與 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
}

然后像這樣在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')],
                    .......
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM