mathjs icon indicating copy to clipboard operation
mathjs copied to clipboard

Load mathjs in a browser module (ES import)

Open josdejong opened this issue 4 years ago • 7 comments

Currently it looks like it's not possible to use mathjs in a browser module like:

<script type="module">
  import { create, all } from 'mathjs'
</script>

I think the existing bundles in dist do not have the right exports to be consumed as an ES module.

What should work (but doesn't) is loading like:

import { create, all} from 'mathjs/main/es/index.js'

I think the reason is that many import paths in the code are missing the explicit "*.js" extension, which is the normal way to go in nodejs and webpack environments, but not in browser ES environments which require a real path to a file.

josdejong avatar May 03 '20 09:05 josdejong

this is not worked for me when import mathjs in vite

diveDylan avatar May 11 '20 02:05 diveDylan

I have read https://nodejs.org/api/esm.html#esm_dual_commonjs_es_module_packages a couple of times to try and work out what we should do. Not yet grokked it completely though.

harrysarson avatar May 11 '20 10:05 harrysarson

@josdejong what is your take on the duel package hazard. Does it apply to mathjs? I cannot remember if we still have global state?

harrysarson avatar May 11 '20 10:05 harrysarson

It's quite complicated :S

mathjs has no global state, you have to create your own mathjs instance with for example create(all, config), and in this instance there is state like the config. It may be possible that some difficulties arise because we integrate for example Complex and BigNumber, I'm not entirely true if mathjs adds methods to these libraries.

josdejong avatar May 12 '20 20:05 josdejong

I think you're correct about the lack of file extension; browser environments expect the full path and filename. Is there a way you could tell Gulp to add the .js to imports when it created the files?

GreenImp avatar Jul 28 '20 01:07 GreenImp

I found a related issue at https://github.com/i18next/i18next/issues/1667#issuecomment-930087226. Since math uses babel to compile ESM through gulp, I think this will be helpful. (Also, the error message explicitly mentioned that it failed to resolve @babel/runtime/helpers/extends.) To mention their solution, they include a bundled ESM file for babel. However, I'm not sure how to do that using gulp and if it will work.

HanchaiN avatar Mar 14 '23 18:03 HanchaiN

Thanks Hanchai for your input, an ESM bundle would indeed solve that because there are no imports without .js extension, it is just a single file.

I had anther look to see if a non-bundle ESM code could work:

  • there are some files without file extension. These are files generated by the Babel plugins @babel/plugin-transform-object-assign and @babel/plugin-transform-runtime

  • Then, we need to specify an import map for all the Node.js modules:

    
    <script type="importmap">
      {
        "imports": {
          "typed-function": "../../node_modules/typed-function/lib/esm/typed-function.mjs",
          "decimal.js": "../../node_modules/decimal.js/decimal.mjs",
          "complex.js": "../../node_modules/complex.js/complex.js",
          "fraction.js": "../../node_modules/fraction.js/fraction.js",
          "javascript-natural-sort": "../../node_modules/javascript-natural-sort/naturalSort.js",
          "escape-latex": "../../node_modules/escape-latex/dist/index.js",
          "seedrandom": "../../node_modules/seedrandom/seedrandom.js",
          "tiny-emitter": "../../node_modules/tiny-emitter/dist/tinyemitter.min.js"
        }
      }
    </script>
    <script type="module">
      import * as math from '../../lib/esm/index.js'
    
      // ...
    </script>
    
  • But then we still have the issue that some of the dependencies are not ESM, so trying to run mathjs fails. That is not solvable on our side.

So all in all, I think generating a single ESM bundle makes a lot of sense (it is also way faster then loading many tiny files). We should make sure though that tree-shaking still works on this bundle. Anyone interested trying this out?

josdejong avatar Mar 15 '23 08:03 josdejong