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 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.
Babel only provides the language manipulation (i.e. the syntax), not the underlying types of objects needed (i.e. the nouns acted on).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With