j obe
j obe

Reputation: 2049

Why does Babel need a polyfill and not transpile some methods by default?

I've been learning through a course how to use babel in Javascript, I understood the idea that babel with the preset "env" transpiles later versions of ES into ES5. However I've come across a scenario where the array "includes" method is not changed at all by babel and doesn't work on IE11, to fix this I've read that there is a babel polyfill which can be used.

I've come across an answer which tried to explain this but I didn't follow it at all. Could someone simply explain why babel by default doesn't handle all ES transpilations and requires a polyfill.

If I understand correctly then a polyfill is something designed to fill a gap to make something work that isn't supported but I thought this is the job that babel is meant to be doing by default.

Upvotes: 4

Views: 1214

Answers (2)

Qiulang
Qiulang

Reputation: 12495

To understand your problem you need to know the difference between transpiler and polyfill, for example, check here What is the difference between polyfill and transpiler? or https://javascript.info/polyfills, simply put, transpiler for new grammar, polyfill for new api.

Babel is a transpiler, whose initial name called 6to5 but that was in 2015. So your words babel with the preset "env" transpiles later versions of ES into ES5 are NOT correct. Babel will transpile your codes for the browsers in your browserslist setting. If you have IE 11 in your browserslist it may transpile the code into ES5 for IE only, but not for other browsers.

But Babel doesn't do polyfill itself, it delegates that to corejs.

Then comes the core question, which part of your codes babel will transpile and which part of your codes babel will let corejs do polyfill. Your second assessment that this is the job that babel is meant to be doing by default is not correct. Babel do that based on browserslist setting in @babel/preset-env. So if your setting do not include IE, or maybe just { "browserslist": "> 1%, not dead" } babel won't do any work for IE.

@babel/preset-env in babel 7 makes babel setting a lot easier. I have several projects started before babel 7, so I have the preset setting like following (with this setting babel will transpile & polyfill for IE 10/11),

        "presets": [
            [
                "env",
                {
                    "targets": {
                        "browsers": [
                            "last 5 Chrome versions",
                            "last 1 Firefox versions",
                            "last 2 Safari versions",
                            "ie 10-11",
                            "last 3 edge versions"
                        ]
                    }
                }
            ]
        ],

PS, for why String.includes belongs to polyfill but not transpiler, you can also check Compiling vs Polyfills with Babel (JavaScript) and Array.includes is the same.

Upvotes: 0

Jake Browning
Jake Browning

Reputation: 218

A polyfill uses the older version of the language itself to implement the newer feature. For example, Babel supports ES6 array.includes by implementing the method in ES5 itself. Something like

Array.prototype.includes = function(val) { 
    return this.indexOf(val) >= 0;
}

On the other hand, babel's core library is a transpiler. This is responsible for converting features of newer versions of javascript to older versions that aren't possible via writing a polyfill in the older version. For example, it would be impossible to write a polyfill for converting ES5's let or const into var, or converting arrow functions into traditional functions. Operations like these need a transpiler to walk through the code and convert it.

Upvotes: 4

Related Questions