Dropping polyfills from Babel runtime transform
See original GitHub issue- I have searched the issues of this repository and believe that this is not a duplicate.
First off, thanks for the work on v1! It’s clear that a lot of hard work has gone into it and it’s turning out great imo 😃
Expected Behavior
When bundling code for modern browsers, material-ui should not import core-js polyfills for things like Map, Set or Promise, let alone older features like Object.keys
or Object.defineProperty
. If users need to support older environments, they can add polyfills themselves. The material-ui docs could mention which polyfills are necessary and suggest inclusion of @babel/polyfill
or individual polyfill libraries.
Current Behavior
The published material-ui source contains lines like:
var _keys = _interopRequireDefault(require("@babel/runtime/core-js/object/keys"));
or in the ES build:
import _Object$keys from "@babel/runtime/core-js/object/keys";
Context
I am already polyfilling things on the global object in my app, rather than ponyfilling like @babel/runtime
does. The @babel/runtime
ponyfills included by material-ui needlessly increase bundle size. It could be helped a bit if I switched to using the @babel/runtime
(core-js) ponyfills in my app, but even then code will be included for very old browsers that my app doesn’t work in anyway.
After gzip, about 7KB of core-js
modules are included through material-ui in my case:
In Babel 6, babel-runtime
always used the polyfills in its helper functions, but the new runtime transform in Babel 7 has an option, useBuiltIns
, to disable this behaviour. I’d suggest these options:
{
"plugins": [
["@babel/transform-runtime", {
// Disables importing polyfills in transformed files
"polyfill": false,
// When transform-runtime imports helpers, use versions that do not import polyfills
"useBuiltIns": true,
}]
]
}
Your Environment
Tech | Version |
---|---|
Material-UI | v1.0.0-beta.47 |
React | v16.3.2 |
Babel | v7.0.0-beta.46 |
I’m happy to work on a patch for this, just opening an issue in advance to check what y’all’s opinion is before I do it.
Issue Analytics
- State:
- Created 5 years ago
- Reactions:1
- Comments:6 (6 by maintainers)
Top GitHub Comments
I’m using
/es
modules but the runtime transform is used for both.That’s true, but the core-js polyfills are adding unnecessary weight when targeting modern browsers or when the app already includes its own polyfills. The material-ui components that are used in my app take 14KB gzipped; the polyfills included by mui add another 7KB.
Suggesting people use
@babel/polyfill
and@babel/preset-env
with theuseBuiltIns
option would be a fairly simple way to include global polyfills in apps that don’t add them manually already, I think.The
/es
folder also includes polyfills forObject.keys
and other runtime features that have shipped in ES standards. eg. https://unpkg.com/material-ui@1.0.0-beta.47/es/styles/withStyles.js includes polyfills forMap
,Object.keys
andNumber.MAX_SAFE_INTEGER
:For my purposes it would also be fine if
/es
didn’t include polyfills while the CJS build did. Unfortunately transform-runtime’s polyfill option is all-or-nothing so we can’t tell it to only include polyfills for proposals that haven’t made it into a yearly spec release yet.It doesn’t look like those files include polyfills, though, only helpers. Setting
polyfill: false
would still add the runtime helpers for syntax features likeobjectWithoutProperties
andobjectSpread
for object rest spread, but it would not include polyfills for runtime language features. This antd file for example usesObject.keys
but does not get a core-js polyfill. I think both those libraries use fewer new runtime features though (nonew Map
or anything as far as I can tell) so they probably don’t need many polyfills to begin with.FWIW I just wanted to bring this up before the v1 release because it would be a breaking change to do it later; if your response is anything but an enthusiastic yes I’m happy to leave it be 😃
Sure, that works for me! Thanks for the Babel issue link; that looks perfect.