15

I am a bit lost in the Babel options / config. I want to use recent js features and compile (with webpack) to browser code.

What is the difference between babel-polyfill and babel plugins with babel-preset-env?

Are they intended to work together?

François Romain
  • 13,617
  • 17
  • 89
  • 123

2 Answers2

31

Answer from this article:

The distinction between a babel transform plugin versus babel-polyfill / babel-runtime is whether or not you can reimplement the feature today, in ES5. For example, Array.from can be rewritten in ES5 but there is nothing I can write in ES5 to add arrow function syntax to JavaScript. Therefore, there is a transform for arrow functions but none for Array.from. It will have to be provided by a separate polyfill like babel-polyfill, or babel-runtime.


As a side note, here is my current understanding of the babel eco-system.

Babel is a javascript compiler: it parses, transforms and outputs transformed code.

babel-core

  • This is the parse and output parts.
  • It does not do any transformation.
  • It can be used from the command line or from a bundler (webpack, rollup and co.)

babel-polyfill / babel-runtime

  • Acts on the transform part by prepending es5 javascript to your code to emulate es2015+ functions (like Object.assign).
  • Relies on Regenerator (to polyfill generators) and core-js (to polyfill all the rest).
  • Difference between babel-polyfill and babel-runtime: the former defines global methods (and pollutes the global scope) whereas the latter transforms your code to make the same functionnality available as explained in this answer.

babel plugins

  • Transform the code you wrote.
  • babel syntax / transform plugins: parse and transform es2015+ syntax (like arrow functions) to convert it to es5.
  • babel-plugins-stage-x (from stage-0 to stage-4): transform future javascript syntax which is not in the JS specs yet, starting at stage-0 (just an idea) down to stage-4 (will land in the babel-plugins soon).

babel-preset-env

  • babel-preset-env determines the Babel plugins and polyfills needed for a specific environment.
  • With no configuration, it will load all the plugins (including es2015, es2016 and es2017) required to transpile es2015+ to es5.
  • With a target option, it loads only the plugins required to run on a specific target.
  • With the builtIn option, it uses only the babel-polyfill which are not built-in the target.
  • Does not work with babel-transform-runtime yet (as of nov. 2017). (see this issue)
François Romain
  • 13,617
  • 17
  • 89
  • 123
  • Would you like to update this answer since we are at 2021? I've been searching on Internet and there are little highly organized answers, so I think keep your answer up to date indeed help more people like me. – NeoZoom.lua Aug 17 '21 at 05:27
  • __babel-polyfill / babel-runtime__ > by prepending es5 javascript: What did you mean _prepending_? – NeoZoom.lua Aug 17 '21 at 05:30
3

babel-preset-env is a Babel preset meant to automatically set up babel plugins and include the necessary babel polyfills based on a set of target environments checked against a feature compatibility table.

In order to make a fully working ES2015+ environment run on a non-ES2015+ client, simple code transpilation is sometimes not enough:

  • ES generators are enabled using regenerator library (provided by babel-polyfill)
  • Missing ES2015+ methods (like Promise, Map, Object.assign...) are polyfilled with core-js (provided by babel-polyfill, too)
  • Any other transpilable feature is generated by standard babel plugins, often used trough pre-configured babel-presets

So, back to your question, it's babel-preset-env that makes use of babel-polyfill and babel plugins.

Irvin Lim
  • 2,393
  • 17
  • 20
Andrea Carraro
  • 9,731
  • 5
  • 33
  • 57