I'm trying to import and use MathJax within a browser-based ESM module using various flavors of importing including the following:
import * as MathJax from 'mathjax/es5/tex-svg';
import 'mathjax/es5/tex-svg';
Attempted usage is as follows:
MathJax.tex2svg(String.raw`${text}`);
This throws a TypeError
stating MathJax2.tex2svg is not a function
. I installed MathJax using:
npm install mathjax
How can one import and use MathJax in a browser-based ESM environment where the dependency is managed by npm. If it's at all helpful, I'm using esbuild for bundling.
Because MathJax components (like tex-svg.js
) accept a configuration that could specify additional components to load, and the loading of those components is asynchronous when done in a browser, MathJax's startup process is asynchronous and mediated by javascript promises. That is, even though your import command does make MathJax
available, it is not yet fully set up at that point. The startup code is run inside a promise, and that promise will not execute until after the next time javascript is idle. Your call to MathJax.tex2svg()
occurs before that next idle time (as the browser performs the two scripts without being idle in between), and so it is being called before MathJax
is fully set up. The commands like tex2svg()
are added to the MathJax
object by the startup code based on the components that are loaded, so that has to occur after all the components are loaded, which means it must be in the promise that runs after asynchronous loading is complete, and that means it is after the next idle time.
There are several ways to hook into MathJax's loading sequence. One would be to use the MathJax.startup.promise, which is resolved after MathJax is set up and does its initial typesetting of the page. So you could try
MathJax.startup.promise.then(() => MathJax.tex2svg(text));
instead.
Alternatively, you can use the MathJax
object to configure MathJax before loading tex-svg.js
, and use the startup.ready()
option to provide a callback when MathJax is fully set up. E.g., make a file mathjax-config.js
containing
window.MathJax = {
startup: {
ready() {
MathJax.myStartup();
MathJax.startup.defaultReady();
}
}
};
and then do
import 'mathjax-config.js';
import 'mathjax/es5/tex2svg';
MathJax.myStartup = () => {
console.log(MathJax.tex2svg(text));
};
Since MathJax.startup.ready()
will not be called until after the first javascript idle time, your MathJax.myStartup()
function will get to be defined before the ready function is called.
Note that tex-svg.js
does not have any exports, so you should just do
import 'mathjax/es5/tex-svg';
not
import * as MathJax from 'mathjax/es5/tex-svg';
The MathJax
is a global variable that will become available after tex-svg.js
is imported.
Also, String.raw`${text}`
is equivalent to just text
, so no need for the extra complication, unless you just mean ${text}
to represent some arbitrary text literal you would use in place of it.