简体   繁体   中英

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.

Both pollyfill 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 pollyfill do that by implementing the feature in the old environment itself. So if we go by Es6 Es5 terminology, polyfill enable 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 and this is where transpilation is needed.

So an example where transpilation is needed is arrow syntax (() => {}) because u can never implement that in es5, and an example where a pollyfil can be used is for example if u wanted to implement the Array.prototype.includes method, you can easily implement it 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 pollyfill 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 pollyfill is about language syntax and native browser APIS.

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

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

so lets 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 into something like the following


var f = function f() {
 // notice that includes stay even though this is an es6 feature, the reason it stays is because babel does not transpile it
 // the following code will break if you dont import a pollyfill using core-js or any other pollyfill library
 return str.includes('fun');
}

i have cut a lot of what babel transpilation output would be, if you wanna see it u can do this here

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

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

ES6 provides more than just new syntax it also adds new functionality like for example:

Number.isInteger(num) checks whether num is an integer (a number without a decimal fraction).

What's new in ES6?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM