【问题标题】:Why does Babel need a polyfill and not transpile some methods by default?为什么 Babel 需要 polyfill 而不是默认转译某些方法?
【发布时间】:2023-02-19 10:47:20
【问题描述】:

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

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

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

【问题讨论】:

    标签: javascript webpack babeljs ecmascript-5


    【解决方案1】:

    polyfill 使用旧版本的语言本身来实现新功能。例如,Babel 通过在 ES5 本身中实现该方法来支持 ES6 array.includes。就像是

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

    另一方面,babel 的核心库是一个转译器。这负责将较新版本的 javascript 的功能转换为旧版本,而这些功能无法通过在旧版本中编写 polyfill 来实现。例如,不可能编写将 ES5 的 letconst 转换为 var 或将箭头函数转换为传统函数的 polyfill。像这样的操作需要一个转译器来遍历代码并将其转换。

    【讨论】:

    • 好吧,我仍然不清楚你的回答,当然转译器最终也必须使用旧版本的语言来实现新功能,所以定义相同。还有为什么 babel 不能默认这样做?为什么需要单独的 polyfill 包?
    • 转译器使用它编写的任何语言来遍历目标文件的源代码并吐出转译后的版本。我可以用 C 编写一个 javascript 转译器,遍历 ES6 源代码,并简单地将 constlet 的每个实例替换为 var。这是一个非常简单的转译器的例子。 “为什么需要单独的 polyfill 包?” -- 转译与 polyfilling 非常不同,babel 主要是一个转译器。我猜这是 Babel 团队做出的将它们分开的设计决定。
    • 如果 includes 是一个新的数组方法,为什么 babel 不默认创建该方法以便它可以在旧浏览器中使用,为什么需要 babel polyfill?如果 babel 转译 const 和 let 到 var 的原理不一样,拿不支持的东西创建支持的版本?
    • 我猜你的问题基本上是“为什么 babel 不在它的核心包中包含它的 polyfills”?可能是因为 polyfills 在运行时减慢了 JS 的速度,而 babel core 在设计上非常小。然后你可以问“为什么 babel 不转译 includes 而不是 polyfilling”?可能是因为在可能的情况下对旧功能进行 polyfill 会加快转译时间。我想这是 Babel 维护者考虑的权衡平衡。如果发生在这个线程中,他们可以给出更明确的答案
    • 我理解为什么 Babel 默认支持某些 ES6 特性而不支持其他特性令人困惑。我认为在理想的世界中,Babel 会支持所有这些开箱即用的工具,但他们决定排除 polyfill 至少部分是因为我上面提到的限制。至于模糊的界线,Babel 的 polyfilling 和 transpiling 有相同的目标——支持更新的 JS——但这两个过程是完全不同的事情。深入了解它们之间的技术差异可能会有所帮助。
    【解决方案2】:

    要了解您的问题,您需要了解两者之间的区别转译器polyfill,比如这里勾选What is the difference between polyfill and transpiler?https://javascript.info/polyfills,简单来说,transpiler for new grammar,polyfill for new api。

    Babel 是一个转译器,最初的名字叫6to5,但那是在 2015 年。所以你的话带有预设“env”的 babel 将 ES 的更高版本转换为 ES5不正确。 Babel 将在您的浏览器列表设置中为浏览器转换您的代码。如果您的浏览器列表中有 IE 11,则可能会将代码转译为 ES5,仅适用于 IE,但不适用于其他浏览器。

    但是 babel 不会自己做 polyfill,而是将其委托给 corejs。

    那么核心问题来了,你的哪部分代码babel会转译你的哪部分代码babel会让corejs做polyfill。你的第二个评估是这是 babel 默认要做的工作是不正确的。 Babel 根据@babel/preset-env 中的浏览器列表设置来执行此操作。因此,如果您的设置不包括 IE,或者可能只是 { "browserslist": "> 1%, not dead" } babel 将不会为 IE 做任何工作

    【讨论】:

      猜你喜欢
      • 2020-08-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-07
      • 1970-01-01
      • 1970-01-01
      • 2019-07-07
      相关资源
      最近更新 更多