If you're trying to grasp the essence of your issue, it's crucial to grasp the distinction between a transpiler and a polyfill. For more insights, you can refer to the following resources: Difference Between Polyfill and Transpiler or Polyfills in JavaScript. In simple terms, a transpiler is for new syntax while a polyfill is for new APIs.
Babel serves as a transpiler, previously known as 6to5, back in 2015. Therefore, claiming that "Babel with the 'env' preset transpiles later versions of ES into ES5" is inaccurate. Babel transpiles your code according to the browsers listed in your browserslist configuration. If IE 11 is included in your list, it will transpile the code into ES5 specifically for IE but not for other browsers.
Although Babel doesn't handle polyfills on its own, it relegates that task to core-js.
The pivotal question then arises – which parts of your code does Babel transpile and where does it hand over the polyfill responsibility to core-js? Asserting that "this is the job that Babel is meant to be doing by default" is incorrect. Babel performs these tasks based on your browserslist settings within @babel/preset-env. Hence, if IE is not part of your configuration or you have explicit settings like
{ "browserslist": "> 1%, not dead" }
, Babel won't cater to IE compatibility.
@babel/preset-env
in Babel 7 simplifies the setup process significantly. My previous projects initiated before Babel 7 had presets configured as follows (this setting enables both transpilation and polyfilling 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"
]
}
}
]
],
Lastly, to understand why String.includes
falls under polyfill rather than transpilation, you can delve into articles like Compiling vs Polyfills with Babel (JavaScript). The same applies to Array.includes
.