Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I'm working on a web project using Babel 7 with Webpack 4. I've never used Babel before and can't really understand some parts of it. Based on the documentation I'm using @babel/preset-env because it seems the recommended way (especially for beginners). Also using Browserslist integration via my .browserslistrc file.

Webpack does the compilation well ( babel-loader version 8.0.2 ), I have no errors but I'm confused about this useBuiltIns: "entry" option mentioned here and how polyfill system is working in Babel.

.babelrc.js

module.exports = {
  presets: [
    ['@babel/preset-env', {
      "useBuiltIns": "entry" // do I need this?
  plugins: [
    '@babel/plugin-syntax-dynamic-import'

.browserslistrc
Copied from here (thought reasonable because my project is using Bootstrap).

last 1 major version not dead Chrome >= 45 Firefox >= 38 Edge >= 12 Explorer >= 10 iOS >= 9 Safari >= 9 Android >= 4.4 Opera >= 30

So my questions are:

1) Do I need to use that useBuiltIns: "entry" option?

2) Do I need to install @babel/polyfill package and start my vendors.js with require("@babel/polyfill"); ?

3) What if I omit both?

If I do 1 and 2, my vendors.js grows up to 411 KB
If I ommit both it's just 341 KB
after a production build.

I thought @babel/preset-env handles all the rewrites and polyfills by default without any extra import/require needed on my side...

Thanks!

-- EDIT --

Babel's team has just updated the docs of @babel/polyfill based on some GitHub issues (including mine) complaining about unclear/misleading documentation. Now it's obvious how to use it. (...and after that my original question seems stupid :)

There're basically 3 options for useBuiltIns:

"entry": when using this option, @babel/preset-env replaces direct imports of core-js to imports of only the specific modules required for a target environment.

That means you need to add

import "core-js/stable";
import "regenerator-runtime/runtime";

to your entry point and these lines will be replaced by only required polyfills. When targeting chrome 72, it will be transformed by @babel/preset-env to

import "core-js/modules/es.array.unscopables.flat";
import "core-js/modules/es.array.unscopables.flat-map";
import "core-js/modules/es.object.from-entries";
import "core-js/modules/web.immediate";

"usage": in this case polyfills will be added automatically when the usage of some feature is unsupported in target environment. So:

const set = new Set([1, 2, 3]);
[1, 2, 3].includes(2);

in browsers like ie11 will be replaced with

import "core-js/modules/es.array.includes";
import "core-js/modules/es.array.iterator";
import "core-js/modules/es.object.to-string";
import "core-js/modules/es.set";
const set = new Set([1, 2, 3]);
[1, 2, 3].includes(2);

In case target browser is latest chrome, no transformations will apply.

That's personally my chosen weapon as there's no need to include anything (core-js or regenerator) in source code as only required polyfills will be added automatically based on target environment set in browserlist.

false: that's the default value when no polyfills are added automatically.

2) Do I need to install @babel/polyfill package and start my vendors.js with require("@babel/polyfill"); ?

Yes for environment prior to babel v7.4 and core-js v3.

TL;DR

No. Starting from babel v7.4 and core-js v3 (which is used for polyfilling under the hood) @babel/preset-env will add the polyfills only when it know which of them required and in the recommended order.

Moreover @babel/polyfill is considered as deprecated in favor of separate core-js and regenerator-runtime inclusions.

So using of useBuiltIns with options other than false should solve the issue.

Don't forget to add core-js as a dependency to your project and set its version in @babel/preset-env under corejs property.

When using "usage" I must use import "core-js/stable"; import "regenerator-runtime/runtime"; ? – Max Jul 15, 2019 at 16:30 Good answer. The Babel documentation says: "When either the usage or entry options are used, @babel/preset-env will add direct references to core-js modules as bare imports (or requires). This means core-js will be resolved relative to the file itself and needs to be accessible." is very hard to understand without context or examples. – Richard Hunter Nov 3, 2020 at 4:26

Yes, according to babel docs:

"This option enables a new plugin that replaces the statement import "@babel/polyfill" or require("@babel/polyfill") with individual requires for @babel/polyfill based on environment" - Basically, includes all needed polyfills (when you have @babel/polyfill installed when needed).

2) Do I need to install @babel/polyfill package and start my vendors.js with require("@babel/polyfill"); ?

You do need to install @babel/polyfill, it does not come by default on babel. You have to include that on your entrypoint or add an import at the top of your entrypoint.

3) What if I omit both?

You won't have polyfills.

Thank you, now I understand. Meanwhile I've read the docs of babel-polyfill and this part was really useful: babeljs.io/docs/en/babel-polyfill#size – szegheo Oct 3, 2018 at 12:55 The language surrounding this topic is pretty confusing and initially seems to contradict itself...It's not immediately clear that what is meant is that the import "@babel/polyfill" statement IS necessary at the top of your entrypoint, and when useBuiltIns: 'entry' is used, this statement gets AUTOMATICALLY replaced for you to import individual needed polyfills at build time – Roman Scher Mar 28, 2019 at 2:34 Note that if you set useBuiltIns to "usage", you don't have to add @babel/polyfill to the entry array anymore. babeljs.io/docs/en/… – Paul Razvan Berg Apr 24, 2019 at 12:29

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.