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

Using MathJax node in an ES module #54

Closed
rnwst opened this issue Dec 16, 2022 · 2 comments
Closed

Using MathJax node in an ES module #54

rnwst opened this issue Dec 16, 2022 · 2 comments
Labels

Comments

@rnwst
Copy link

rnwst commented Dec 16, 2022

I have a node project which is an ES module (package.json contains "type": "module"). I'm trying to use MathJax to typeset an HTML page server-side. The demos use the shebang #! /usr/bin/env -S node -r esm, which preloads esm. This allows mixing CJS module (require() and module.exports) and ESM (import and export) syntax. If I use the same shebang, I get the following error:

Error [ERR_REQUIRE_ESM]: require() of ES Module /path/to/project/file.js not supported.
Instead change the require of file.js in null to a dynamic import() which is available in all CommonJS modules.] {
  code: 'ERR_REQUIRE_ESM'
}

If I change the shebang to #!/usr/bin/env node, mixed CJSM and ESM syntax no longer works:

(node:23193) Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.
(Use `node --trace-warnings ...` to show where the warning was created)
/path/to/project/node_modules/mathjax-full/components/src/node-main/node-main.js:83
export {init};
^^^^^^

SyntaxError: Unexpected token 'export'

Using esm isn't really an acceptable option for me in the first place, as it hasn't seen any commits since 2019 and doesn't support modern Javascript features like optional chaining. Therefore, the real issue it seems to me is that MathJax is mixing CJSM and ESM syntax.

Is there any way I can use MathJax in an ES module?

Version info:
node v19.2.0
[email protected]
[email protected]

@dpvc
Copy link
Member

dpvc commented Dec 23, 2022

MathJax's typescript source is compiled into ES5 .js files, and since ES5 predates import/export, those .js files use require(). So the first thing you would ned to do is modify the tsconfig file to output ES6 my changing

    "target": "ES5",

to

    "target": "ES6",

and also probably also change the exclude to list es6.

Then recompile MathJax using

npm run -s compile

Then if you are using components rather than direct calls to the MathJax modules, you will need to rebuild the components. You may want to adjust the components/webpack.common.js file to change the es5 references to es6 (so that it builds the components into an es6 directory rather than the current es5 one). There are a couple of copy.json files that you might want to direct to the es6 directory as well. Use

grep -r es5 components/

to find them and see if they are for components that you will be using.

Then rebuild the components

npm run -s make-components

Then you should be able to import the components from the es6 directory, or the .js files from the js directory.

The examples in this demo repository are just samples, not part of MathJax proper, and you should be able to convert the require() commands to import commands easily enough, other than the ones in the simple directory, as those use the components/src/node-main/node-main.js file, which uses require and would need to be modified to avoid that. Your best bet is probably the examples in the components directory (or the direct directory if you don't want to use the mathJax components architecture).

@dpvc dpvc added the Question label Dec 23, 2022
@rnwst
Copy link
Author

rnwst commented Jan 15, 2023

Many thanks for the detailed instructions!

@rnwst rnwst closed this as completed Jan 15, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants