为什么 Babel 需要一个 polyfill 而不是默认转译某些方法?

问题描述 投票:0回答:2

我一直在学习如何在 Javascript 中使用 babel,我理解了带有预设“env”的 babel 将 ES 的更高版本转换为 ES5 的想法。但是我遇到了一个场景,其中数组“includes”方法根本没有被 babel 改变并且在 IE11 上不起作用,为了解决这个问题,我读到有一个可以使用的 babel polyfill。

我遇到了一个试图解释这一点的答案,但我根本没有遵循它。有人可以简单地解释一下为什么默认情况下 babel 不处理所有 ES 转译并需要一个 polyfill。

如果我理解正确,那么 polyfill 是一种旨在填补空白以使不受支持的东西工作的东西,但我认为这是 babel 默认情况下应该做的工作。

javascript webpack babeljs ecmascript-5
2个回答
3
投票

polyfill 使用语言本身的旧版本来实现新功能。比如 Babel 通过自己实现 ES5 中的方法来支持 ES6

array.includes
。有点像

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

另一方面,babel 的核心库是一个转译器。这负责将较新版本的 javascript 的功能转换为旧版本,而这些功能无法通过在旧版本中编写 polyfill 来实现。例如,将 ES5 的

let
const
转换为
var
,或将箭头函数转换为传统函数,就不可能编写一个 polyfill。像这样的操作需要一个转译器来遍历代码并转换它。


0
投票

要了解您的问题,您需要了解 transpilerpolyfill 之间的区别,例如,请查看此处polyfill 和 transpiler 之间的区别是什么? put,新语法的转译器,新 api 的 polyfill。 Babel 是一个转译器,最初的名字叫 6to5

但那是在 2015 年。所以你的话

babel 带有预设“env”将 ES 的更高版本转译为 ES5 是不正确的。 Babel 将在您的浏览器列表设置中为浏览器转换您的代码。如果您的浏览器列表中有 IE 11,它可能会将代码转换为 ES5,仅适用于 IE,但不适用于其他浏览器。 但是 Babel 本身并不做 polyfill,而是将其委托给 corejs。

然后就是核心问题,你的代码babel哪部分会transpile,你的代码babel哪部分让corejs做polyfill。你的第二个评估是

这是 babel 默认要做的工作

是不正确的。 Babel 根据 @babel/preset-env 中的浏览器列表设置来执行此操作。所以如果你的设置不包括 IE,或者可能只是 { "browserslist": "> 1%, not dead" } babel 不会为 IE 做任何工作。

@babel/preset-env 在 babel 7

 中使 babel 设置更容易。我有几个项目在 babel 7 之前开始,所以我有如下预设设置(使用此设置 babel 将为 IE 10/11 转换和 polyfill),
"presets": [ [ "env", { "targets": { "browsers": [ "last 5 Chrome versions", "last 1 Firefox versions", "last 2 Safari versions", "ie 10-11", "last 3 edge versions" ] } } ] ],

PS,为什么
String.includes

属于polyfill而不属于transpiler,你也可以查看

Compiling vs Polyfills with Babel (JavaScript)
Array.includes是一样的。
    

© www.soinside.com 2019 - 2024. All rights reserved.