josdejong / mathjs

An extensive math library for JavaScript and Node.js
https://mathjs.org
Apache License 2.0
14.32k stars 1.24k forks source link

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

Open josdejong opened 4 years ago

josdejong commented 4 years ago

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 commented 4 years ago

this is not worked for me when import mathjs in vite

harrysarson commented 4 years ago

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 commented 4 years ago

@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 commented 4 years ago

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 commented 4 years ago

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 commented 1 year ago

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.

josdejong commented 1 year ago

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:

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?