Slate: Use babel-preset-env

Created on 17 Jul 2017  Â·  4Comments  Â·  Source: ianstormtaylor/slate

Do you want to request a feature or report a bug?

Want to request a feature.

What's the current behavior?

Currently for older browser like IE11 and lower it requires you to include a babel-polyfill instance. Which is not really tiny, and makes the total payload of this package a bit huge. Would it be an idea to switch to using babel-runtime and babel-preset-env, which is in my opinion more suitable for libraries.

babel-runtime and babel-preset-env does automatically include only the needed polyfills within the bundle, which could result also in an easier setup of the package.

@ianstormtaylor what are your opinions about this? I am happy to provide a PR for it.

idea ♥ help

Most helpful comment

I originally commented on #1554 but moving my comment over here since the PR was closed


@ianstormtaylor I recommend this article to get some quick background on the babel configuration being discussed.

There are a couple of somewhat orthogonal issues being discussed here. To try to sum up:

  • babel-preset-es2015 vs babel-preset-env

    • babel-preset-es2015 will transpile all ES2015 features to ES5, without consideration for what browser(s) will be running the output code

    • babel-preset-env takes a slightly smarter approach: you tell it what browsers you want to support (via either a browserslist or via configuring the preset options in .babelrc) and it will analyze your supported browsers and transpile ES2015 features not supported by the lowest common denominator. ES2015 code that all of your supported browsers have implemented will be left as ES2015.

    • I think there's a clear benefit to moving to babel-preset-env, but we would have to make a firm decision on what browsers we support and add that configuration in order to actually see benefits from it. Also it would represent a sort-of-breaking change, if someone is using slate with a browser that we don't technically support but that happens to work currently (but would break if we dropped transpilations for it) -- IE11 seems like a potential victim here.

  • babel-polyfill vs. babel-runtime

    • This distinction has to do with newer built-ins/primitives -- things like Set or Map that need to be polyfilled rather than transpiled. It is not clear to me whether Slate currently uses anything that would necessitate this (though it's not hard to figure out with a little work).

    • The "old" solution is for the end user to include babel-polyfill to polyfill all the new primitives that might be missing in older browsers. babel-polyfill will intentionally "pollute" the global scope, i.e. define globals for Set, Map, and all the rest. This makes it unsuitable for use in libraries (since you don't want to hammer whatever the end user is doing with their global scope, i.e. if they have their own polyfills). As a result, if your library uses new primitives, the end user is forced to add babel-polyfill to support some browsers, which increases the effective footprint of your library.

    • The "new" solution is babel-runtime which will transpile your code to reference corejs directly rather than expecting globals. For example Set would become a reference to require('babel-runtime/core-js/set'). Also, small helpers inserted by Babel (like __extend) also become references to a single module implementation rather than having potential duplication.

    • The benefit here is a bit fuzzier to me. I think we should first identify to what extent Slate uses primitives that require polyfilling in the first place (similar caveat as above about explicit vs. implicit browser support). The added cost is that you must add babel-runtime to your "dependencies" which might reflect unnecessary added weight if we don't actually need to polyfill m/any features for our supported browsers.

All 4 comments

Hey @jbovenschen thanks, I know nothing about the latest in Babel config because I haven't been paying attention, but I'm open to it if you want to make a PR. I'd just need a bit of explanation to feel comfortable merging it. Thanks!

I originally commented on #1554 but moving my comment over here since the PR was closed


@ianstormtaylor I recommend this article to get some quick background on the babel configuration being discussed.

There are a couple of somewhat orthogonal issues being discussed here. To try to sum up:

  • babel-preset-es2015 vs babel-preset-env

    • babel-preset-es2015 will transpile all ES2015 features to ES5, without consideration for what browser(s) will be running the output code

    • babel-preset-env takes a slightly smarter approach: you tell it what browsers you want to support (via either a browserslist or via configuring the preset options in .babelrc) and it will analyze your supported browsers and transpile ES2015 features not supported by the lowest common denominator. ES2015 code that all of your supported browsers have implemented will be left as ES2015.

    • I think there's a clear benefit to moving to babel-preset-env, but we would have to make a firm decision on what browsers we support and add that configuration in order to actually see benefits from it. Also it would represent a sort-of-breaking change, if someone is using slate with a browser that we don't technically support but that happens to work currently (but would break if we dropped transpilations for it) -- IE11 seems like a potential victim here.

  • babel-polyfill vs. babel-runtime

    • This distinction has to do with newer built-ins/primitives -- things like Set or Map that need to be polyfilled rather than transpiled. It is not clear to me whether Slate currently uses anything that would necessitate this (though it's not hard to figure out with a little work).

    • The "old" solution is for the end user to include babel-polyfill to polyfill all the new primitives that might be missing in older browsers. babel-polyfill will intentionally "pollute" the global scope, i.e. define globals for Set, Map, and all the rest. This makes it unsuitable for use in libraries (since you don't want to hammer whatever the end user is doing with their global scope, i.e. if they have their own polyfills). As a result, if your library uses new primitives, the end user is forced to add babel-polyfill to support some browsers, which increases the effective footprint of your library.

    • The "new" solution is babel-runtime which will transpile your code to reference corejs directly rather than expecting globals. For example Set would become a reference to require('babel-runtime/core-js/set'). Also, small helpers inserted by Babel (like __extend) also become references to a single module implementation rather than having potential duplication.

    • The benefit here is a bit fuzzier to me. I think we should first identify to what extent Slate uses primitives that require polyfilling in the first place (similar caveat as above about explicit vs. implicit browser support). The added cost is that you must add babel-runtime to your "dependencies" which might reflect unnecessary added weight if we don't actually need to polyfill m/any features for our supported browsers.

Was this page helpful?
0 / 5 - 0 ratings