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

Load mathjs in a browser module (ES import) #1841

Open
josdejong opened this issue May 3, 2020 · 7 comments
Open

Load mathjs in a browser module (ES import) #1841

josdejong opened this issue May 3, 2020 · 7 comments

Comments

@josdejong
Copy link
Owner

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.

@diveDylan
Copy link

this is not worked for me when import mathjs in vite

@harrysarson
Copy link
Collaborator

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
Copy link
Collaborator

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

@josdejong
Copy link
Owner Author

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.

@GreenImp
Copy link
Contributor

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?

@HanchaiN
Copy link
Contributor

I found a related issue at i18next/i18next#1667 (comment). 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.

@josdejong
Copy link
Owner Author

josdejong commented Mar 15, 2023

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?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants