为什么 Babel 6 有一些(不必要的)代码转换

Why does Babel 6 some (unnecessary) code transformations

在这个简单的 Babel (6.1.18) 示例中 babel --presets es2015 test.js 转换:

'use strict'; // enable strict mode

(function () {
    const A = 3;
}());

'use strict' // enable strict mode
;
(function () {
    var A = 3;
})();

这主要是出于好奇,但我有兴趣更好地理解原因: - 第一行中分号的位置已移至单独的一行 - iife 的语法已从 (function () {}()); 更改为 (function () {})();

Babel 是一个转译器,其工作方式与编译器非常相似:

  1. Babel 对您的代码进行词法分析。这意味着它被标记化了。 (function(){})() 成为标记流,例如 "(" "function" "(" ")" ...

  2. babel 创建语法树。代表您的程序的线性令牌流被转换成这样的树:

  3. babel 然后对你的代码进行语义分析。这是它检查错误、确保您的代码是合法的 ECMA6 代码、添加缺少的分号并确保语法树是合法程序的时候

  4. babel 从语法树javascript 生成代码

因此您可以看到,有几种方法可以编写相同的代码,但是当执行语义分析和代码生成时,会生成相同的代码。

摘要 语法树不保留格式信息,例如调用括号是在分组运算符的外部还是内部。实际上,分组运算符((...))是not even represented in the AST.

这就是人们致力于 Concrete Syntax Tree implementation 的原因,它将包含此类信息以及代码生成器随后可以使用的内容以更接近原始源代码。

有些工具可以重用原始代码,如果那部分代码没有改变(例如 recast),但因为 Babel 主要专注于为浏览器转换代码,这可能是不太重要。现在 Babel 变得更像是一个平台,这可能会改变。