Skip to content

Add core-js polyfill for lib/browser#2266

Merged
josdejong merged 5 commits into
josdejong:developfrom
cshaa:patch-corejs
Jul 7, 2021
Merged

Add core-js polyfill for lib/browser#2266
josdejong merged 5 commits into
josdejong:developfrom
cshaa:patch-corejs

Conversation

@cshaa
Copy link
Copy Markdown
Collaborator

@cshaa cshaa commented Jun 27, 2021

This PR injects all necessary core-js polyfills into lib/browser/math.js. This should fix #2245, however I couldn't check it since I don't have a Windows machine.

  • Pros
    • good backwards compatibility, works even in Node v1.0.0
    • only polyfills functions we use, thanks to Babel's useBuiltIns
    • only affects lib/browser/math.js, the CommonJS and ESM exports are unaffected
  • Cons
    • pollutes global scope & prototypes (things like window.Symbol and Array.from will be defined)
    • increases the size of lib/browser/math.js by 126 kB 40 kB (from 600 kB to 726 kB 640 kB)
    • core-js has a history of controversial advertisements

How I tested it:

$ npm install
$ nvm use 1.0
Now using io.js v1.0.4 (npm v2.3.0)

$ node
> Symbol = Map = Set = Map.from = Set.from = Array.from = Map.prototype[Symbol.iterator] =
    Set.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator] = undefined

> var math = require('./lib/browser/math.js')

> math.evaluate('sqrt(-4)')
{ [String: '2i'] re: 0, im: 2 }

> .exit

$ nvm use system
Now using system version of node: v15.14.0 (npm v7.12.1)

@josdejong
Copy link
Copy Markdown
Owner

Thanks a lot Michal for working out this solution! I can confirm this indeed solves the issue 👍

The growth of the bundle from 600 kB to 726 kB is huge, that is quite a bummer :( ! It would be nice to see if there are alternative solutions, it's a bit of a pity to have to do this just to support an old browser that is hardly used anymore already.

Some ideas:

  1. Maybe we can conditionally load the code using generator/Symbol: if (typeof Symbol !== 'undefined') {...}. If the end user wants to use generators and support IE11, the user has to make sure the required polyfills are loaded. If the user doesn't load these polyfills, apparently he doesn't need generators in the first place.

  2. Do not package the polyfills in the bundle itself, but document that if you want support for IE11, you have to load such a polyfill yourself (this was common practice for IE 9/10/11 with the es5-shim and es6-shim polyfills for example).

  3. Can it be that the current solution bundles the whole of core-js instead of just the features (generator, Symbol) that we actually use? Or do we have to configure the babel preset targets such that it "automatically" includes everything needed to support IE11?

I'll send you an invite for browserstack so you can test on IE11 yourself too :)

@cshaa
Copy link
Copy Markdown
Collaborator Author

cshaa commented Jun 30, 2021

Turns out I misunderstood the Babel documentation (or it's wrong, idk). The option useBuiltIns: 'entry' indeed does include a ton of stuff that we don't need. I changed it to useBuiltIns: 'usage' and voilà, the size is down to 639 kB 😁️

Is 40 kB increase of bundle size acceptable, or should I investigate other options? This increase should only affect people who use lib/browser/math.js directly or via unpkg. People who use math.js via NPM and bundle their dependencies themselves will still have the same experience (i.e. bundle size is still the same and math.js won't work in old browsers unless you import a polyfill yourself).

@cshaa
Copy link
Copy Markdown
Collaborator Author

cshaa commented Jul 1, 2021

It seems to work fine in IE 11, and even IE 10.

image

@Schnark
Copy link
Copy Markdown

Schnark commented Jul 1, 2021

I can confirm that it now works fine in Firefox 16.

@josdejong
Copy link
Copy Markdown
Owner

Turns out I misunderstood the Babel documentation (or it's wrong, idk). The option useBuiltIns: 'entry' indeed does include a ton of stuff that we don't need. I changed it to useBuiltIns: 'usage' and voilà, the size is down to 639 kB 😁️

Is 40 kB increase of bundle size acceptable, or should I investigate other options? This increase should only affect people who use lib/browser/math.js directly or via unpkg. People who use math.js via NPM and bundle their dependencies themselves will still have the same experience (i.e. bundle size is still the same and math.js won't work in old browsers unless you import a polyfill yourself).

woohoo 🎉 that's good news!

40 kB increase is a serious amount, but I think it's acceptable. Like you explain it's only for people importing the bundled version, and those people probably do not want to have to worry about adding polyfills themselves and just want it to "work". Also, there is an escape: you can import the ES or CommonJs version, to do the bundling yourself with/without any polyfills (depending on the browsers you need to support).

I'll merge your fix now, thanks again for working this out!

@josdejong josdejong merged commit c7b09fe into josdejong:develop Jul 7, 2021
@josdejong
Copy link
Copy Markdown
Owner

@m93a shall we switch to use Nodejs 16 and npm 7 during development? Then the package-lock.json file will be changed to v2. We both need to use npm 7, else we get flip-flopping between v1 and v2 when we install/update dependencies.

@josdejong
Copy link
Copy Markdown
Owner

Fix published now in v9.4.4 🎉

@cshaa
Copy link
Copy Markdown
Collaborator Author

cshaa commented Jul 7, 2021

@m93a shall we switch to use Nodejs 16 and npm 7 during development? Then the package-lock.json file will be changed to v2. We both need to use npm 7, else we get flip-flopping between v1 and v2 when we install/update dependencies.

That's a good point, we should coordinate to use the same version of Node :) I don't have strong feelings about which version to use, Node 16 sounds good to me 👍

@josdejong
Copy link
Copy Markdown
Owner

Okido!

josdejong added a commit that referenced this pull request Jul 7, 2021
@josdejong
Copy link
Copy Markdown
Owner

lock file is upgraded now, see f048e2c

joshhansen pushed a commit to LearnSomethingTeam/mathjs that referenced this pull request Sep 16, 2021
* added core-js polyfills for lib/browser/math.js

* exclude defaultInstanceCorejs from lib/esm and lib/cjs

* removed a semicolon

* changed useBuiltIns to usage

Co-authored-by: Jos de Jong <wjosdejong@gmail.com>
joshhansen pushed a commit to LearnSomethingTeam/mathjs that referenced this pull request Sep 16, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

No longer ES5 compatible due to use of Symbol

3 participants