Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support ESM config file #5379

Closed
lukejgaskell opened this issue Aug 18, 2021 · 13 comments · Fixed by #9317
Closed

Support ESM config file #5379

lukejgaskell opened this issue Aug 18, 2021 · 13 comments · Fixed by #9317
Labels
proposal This issue is a proposal, usually non-trivial change
Milestone

Comments

@lukejgaskell
Copy link

lukejgaskell commented Aug 18, 2021

📚 Documentation

Remark and Rehype are ES6 Modules only now and the documentation imports them as CommonJS modules.

Page that that does work as described: https://docusaurus.io/docs/next/markdown-features/plugins

The documentation just says to install those packages

yarn add remark-images

and import them as

const remarkImages = require('remark-images');`

The remark-images package is ESM only and is not able to be required. The docusaurus.config.js is a CJS module and can't include that package.

If it is just an older version of those plugins need to be specified, then that makes sense, but might be nice to have in the docs.

Edit: added more details

@lukejgaskell lukejgaskell added documentation The issue is related to the documentation of Docusaurus status: needs triage This issue has not been triaged by maintainers labels Aug 18, 2021
@slorber
Copy link
Collaborator

slorber commented Aug 19, 2021

Can you explain exactly what you mean?
Please link to external pages that explain the problem if needed.

I'm not able to understand:

  • what problems did you face that I can reproduce (and eventually look for a workaround)
  • what we should change in our documentation
  • what actions do you expect from maintainers

Note Docusaurus is not compatible with the latest versions of remark/rehype.
For now we stick to MDX 1.6 and Remark 12.

@Josh-Cena
Copy link
Collaborator

Josh-Cena commented Aug 19, 2021

Here's an unsuccessful version bumping for rehype-katex: Computerization/computerization.github.io#408

Build is failing because rehype-katex is now ESM-only (https://github.com/remarkjs/remark-math/releases/tag/rehype-katex%406.0.0). This is not a problem with Remark 12/13, just how imports are handled.

It seems docusaurus.config.js is unhappy about using ESM import/export, so I've just kept the older, CJS rehype-katex instead.

I'm not so familiar with this, but I wonder why would ESM import fail when I'm on Node v16?

The code below uses rehype-katex@6.0.0:

Import method

Error

import rehypeKatex from 'rehype-katex';
SyntaxError: Cannot use import statement outside a module
const rehypeKatex = import('rehype-katex');

rehype-katex actually not loaded because it's loaded asynchronously

const rehypeKatex = require('rehype-katex');
Error [ERR_REQUIRE_ESM]:
Must use import to load ES Module: node_modules/rehype-katex/index.js
require() of ES modules is not supported.
require() of node_modules/rehype-katex/index.js from
docusaurus.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 node_modules/rehype-katex/package.json.

@slorber
Copy link
Collaborator

slorber commented Aug 19, 2021

I'm not so familiar with this, but I wonder why would ESM import fail when I'm on Node v16?

I don't know.

Try running node docusaurus.config.js, if it fails too, then it's an error that is not related to Docusaurus.


It seems docusaurus.config.js is unhappy about using ESM import/export, so I've just kept the older, CJS rehype-katex instead.

Is it really Docusaurus?

Make sure to replace module.exports with export default and all the cjs imports to ESM, not mixing cjs/esm.

Then again if node docusaurus.config.js fails it's not Docusaurus's fault.

I'd try to add a .mjs extension, or add { "type": "module" } in site package.json, or at least make sure you can import that lib in a standalone node script

But it's likely that we'll need to add proper support for ESM in all packages

@Josh-Cena
Copy link
Collaborator

It took me much longer than I thought to make node docusaurus.config.js work 😅

But in the end you can't require an ESM module, so Docusaurus still cannot load the config correctly. I find it quite painful that I can't interleave ESM and CJS with each other in Node

Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: docusaurus.config.js
require() of ES modules is not supported.

Some day we are going to make all the packages ESM (by changing the TS target), but that will be when we drop Node v10 support (which I hope is soon, it's not even maintained anymore)

@slorber slorber changed the title Remark / Rehype documentation doesn't work Remark / Rehype ESM imports do not work Aug 19, 2021
@lukejgaskell
Copy link
Author

@slorber @Josh-Cena Thanks for your responses. I updated my question to include more details. As you guys said it seems like Docusaurus just doesn't have support for the config being es6 currently. If there are compatible versions of remark/ rehype plugins, is that listed in the docs somewhere that I just missed?

@Josh-Cena
Copy link
Collaborator

@lukejgaskell I don't know if the doc's wrong in this sense, but at least here we did explicitly state the version: https://docusaurus.io/docs/next/markdown-features/math-equations#configuration. I guess it makes sense to update the doc section you mentioned and explicitly warn that the version matters.

For your question—https://github.com/remarkjs/remark-images/releases/tag/3.0.0 remark-images became ESM in v3, so you can use ^2.0.0 in your package.json for now.

@slorber
Copy link
Collaborator

slorber commented Aug 19, 2021

Yes, we should warn in the doc that users must install plugin versions compatible with cjs (not the latest).

Unfortunately, we can't really maintain an exhaustive compatibility table.
But at least the examples should rather follow our own advice show fixed versions like yarn add remark-images@2


@Josh-Cena we already dropped Node.js 10: https://docusaurus.io/docs/next/installation#requirements

But not sure Node 12 exp support is good enough and in sync with Node 16 support so I'd rather wait a bit more and drop Node 12 too before attempting significant changes, otherwise we may need to support both cjs/esm at the same time and it may be more painful.

@Josh-Cena
Copy link
Collaborator

Josh-Cena commented Oct 28, 2021

After #5812, we are in a good position to consider how we are going to support ESM in our code base.

TypeScript 4.5 is also focusing on prioritizing ESM support, so maybe we can wait till its stable release to test out how that can aid us in the migration.

@Josh-Cena Josh-Cena added proposal This issue is a proposal, usually non-trivial change and removed documentation The issue is related to the documentation of Docusaurus status: needs triage This issue has not been triaged by maintainers labels Oct 28, 2021
@Josh-Cena Josh-Cena changed the title Remark / Rehype ESM imports do not work Support importing ESM modules in config file; full ESM support in code base Oct 28, 2021
@szhshp
Copy link

szhshp commented Jan 14, 2022

Same issue here.

I'm trying to follow the MDX plugin guide in Docusaurus Doc and create a plugin

ESLint popups up and tell me:

'unist-util-visit' should be listed in the project's dependencies. Run 'npm i -S unist-util-visit' to add it

And the latest unist-util-visit is V4.1 but @docusaurus/mdx-loader only support V2 .

Downgrade to V2 solved the issue.

But I still think we may need fully ESM support in future docusaurus

@Josh-Cena
Copy link
Collaborator

@szhshp

  1. It's possible to create ESM MDX plugins, but you have to import it using dynamic import because the config file itself has to be CJS. We now have a bit of a guide on this: https://docusaurus.io/docs/next/markdown-features/math-equations#upgrading-rehype-katex-beyond-recommended-version and we have even upgraded our own internal Remark plugins to ESM: misc: convert all internal scripts to ESM #6286
  2. It's fine to disable extraneous dependencies in your website workspace because there's no downstream consumer for you, and if a package exists, it always exists. Our mdx-loader uses "unist-util-visit": "^2.0.2", as well, as you noticed.

@Josh-Cena Josh-Cena changed the title Support importing ESM modules in config file; full ESM support in code base Support importing ESM modules in config file Jan 20, 2022
@Josh-Cena Josh-Cena added this to the 2.x milestone Mar 25, 2022
@Josh-Cena Josh-Cena changed the title Support importing ESM modules in config file Support ESM config file Apr 5, 2022
@cprice404
Copy link

Just ran into this today when trying to use remark-directive. It's a pretty sharp edge for new folks like me :)

@slorber
Copy link
Collaborator

slorber commented Apr 27, 2023

@cprice404 remark-directive is only for MDX 2 (Docusaurus v3):

The PR (#8288) has only been merged recently (you can try a canary version) and uses remark-directive by default this is how we implement admonitions now) so you don't need to add it manually.

If you want to use ESM remark plugins, now or in the future you can turn your config into an async function:

module.exports = async function createConfig() {
  const plugin = (await import('some-remark-esm-plugin')).default;
  return {
    // ...
  };
}

It's not convenient but it should unlock you until we support ESM in the config file.

@cprice404
Copy link

ah! that's really helpful, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
proposal This issue is a proposal, usually non-trivial change
Projects
None yet
6 participants
@slorber @cprice404 @szhshp @lukejgaskell @Josh-Cena and others