Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do I need @babel/polyfill at all, using Babel?

I'm learning enormous JavaScript ecosystem and I can't understand the following.

Babel is a transpiler, and from the official website:

Babel is a toolchain that is mainly used to convert ECMAScript 2015+ code into a backwards compatible version of JavaScript in current and older browsers or environments.

Since I use the @babel/preset-env present, I assume that this should be enough to write ES6+ code and get it transpiled to some compatible code, according to my browserslist.

Then, I came into this: https://babeljs.io/docs/en/babel-polyfill, which suggest using @babel/polyfill instead of:

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

Instead of the deprecated @babel/polyfill. Now I know what a polyfill is, I used the Intersection Observer polyfill, for example.

So my question is: is this something "automatic" that Babel provides? Some sort of plugin that can polyfill my code, automatically? What are the two libraries that they are talking about? why I need these two additional packages in order to make my code ES5-compatible, if Babel should do it by itself? Consider Object.assign: it will work in IE11 only with core-js package. Why Babel didn't transpiled it?

EDIT: my mistake reading the article, but my question remains the same.

like image 275
gremo Avatar asked Mar 02 '23 11:03

gremo


2 Answers

Both polyfill and transpilation enable you to use new features in old environments (think of old vs new browsers for example), the main difference is that a polyfill does that by implementing the feature in the old environment itself. So if we go by ES6 ES5 terminology, polyfill enables you to use a new feature by implementing it in ES5, however some new features can never be implemented in ES5, think for example about the arrow syntax introduced by ES6 - this is where transpilation is needed.

An example where transpilation is needed is arrow syntax (() => {}) because you can never implement that in ES5, and an example where a polyfill can be used is if you wanted to implement the String.prototype.includes method. That can be implemented like this:

// taken from mdn
if (!String.prototype.includes) {
  String.prototype.includes = function(search, start) {
    'use strict';

    if (search instanceof RegExp) {
      throw TypeError('first argument must not be a RegExp');
    } 
    if (start === undefined) { start = 0; }
    return this.indexOf(search, start) !== -1;
  };
}

Now another important distinction is that a polyfill will use the native feature if it exists, however transpilation will not. That leads to the conclusion that polyfills should be preferred over transpilation, because of security and performance reasons.

Last distinction is that transpilation is about language syntax, while polyfill is about language syntax and native browser APIs.

Long story made short: transpilation is at compile time, while polyfill is at runtime.

Now that the distinction has been made clear, we can see that to use new code and features Babel uses both strategies. The main guideline is to use polyfill when possible; otherwise, transpilation (transpilation will be needed for a new syntax that can never be implemented in the old ES5 environment, itself). So you need to import core-js to polyfill features that could have been enabled by transpilation, but its better to implement them using polyfill.

Let's take some code as an example, to differentiate between the two:

const f = (str) => {
  return str.includes('fun')
}

what Babel will do is transpile that code into something like the following:

var f = function f() {
 // notice that `.includes()` stays. Even though this is
 // an ES6 feature, it stays because
 // Babel does not transpile it.
 // 
 // the following code will break if you don't import
 // a polyfill using core-js or any other polyfill library
 return str.includes('fun');
}

I have cut a lot of what Babel transpilation output would be, if you want to see it you can read here.

And now to your question if Babel uses something automatic to do that. The answer is yes, and that is @babel/preset-env, which will configure the transpilation processes and polyfills needed for you automatically based on your target environment.

like image 168
ehab Avatar answered Mar 07 '23 18:03

ehab


Babel only provides the language manipulation (i.e. the syntax), not the underlying types of objects needed (i.e. the nouns acted on).

like image 43
Daniel A. White Avatar answered Mar 07 '23 19:03

Daniel A. White