babel源码阅读准备工作

272 阅读2分钟

源码版本选择

目前的babel功能已经非常丰富了,源码读起来比较困难,因此选择babel早期的版本进行探索。本文选取的版本为tag v1.7.7的版本。在这个版本时,babel还不叫babel,而是叫做6to5,就是将ES6转成ES5

image.png

源码运行

在这个版本中,有一个bin目录,其中就包含一个可执行文件6to5,可以直接在命令行中输入bin/6to5 -o output.js input.js,就可以测试6to5的功能,其中input.js为输入文件,-o output.js代表将输出内容写到output.js文件中。

以箭头函数为例

const a = (m, n) => m + n;
a(1,2);

输出结果为

(function() {
  var a = function(m, n) {
    return m + n;
  };
  a(1,2);
})();

可以看到6to5将箭头函数转换成了普通函数的形式,并且在最外层包了一层立即执行函数。

调试准备工作

为了方便调试源码,本文使用vscode,并且设置launch.json如下。其中skipFiles为调试时跳过的文件,在这里跳过node_modules文件夹下的文件。

{
    "version": "0.2.0",
    "configurations": [
      {
        "type": "pwa-node",
        "request": "launch",
        "name": "debug Program",
        "skipFiles": ["${workspaceFolder}/node_modules/**"],
        "runtimeExecutable": "node",
        "args": ["./bin/6to5", "-o", "output.js", "input.js"]
      }
    ]
}

源码分析

源码运行顺序

6to5文件中,引入了util文件。

image.png

util文件主要提供了一些函数,在文件的最后是导出语法转换模版,如果提供了templates.json,就直接将该文件的内容作为模版,否则使用6to5中的template目录下定义好的模版。在221行的地方,调用了parse函数来得到模版内容的抽象语法树,并调用removeProperties函数来移除部分对于代码转换无用的属性。

image.png

接下来就是调用transform.js文件中的transform函数,在该函数中,调用了parse函数获取抽象语法树,然后调用traverse函数,可以更改抽象语法树中的节点,最后调用generate函数生成ES5的代码。

断点设置

由于在引入util文件时,就会利用parsetraverse等重要函数来批量生成模版,为了跳过模版的生成过程,直接在调用transform函数处打断点。

image.png

想看transform的具体操作的话,找到transformers目录下对应的文件,打断点。如箭头函数的转换,在6to5中就是将箭头函数的函数体放在ReturnStatement中,并在外层包上BlockStatement,如果有this的话,还要对this进行转换。

image.png