与 Babel 相识相知

90 阅读4分钟

从零开始学习 babel,从认识 babel 是什么东西、有什么用到明白如何使用 babel,做些有意思的小工具。

一、Babel 的介绍

1. 什么是 Babel ?

babel 最开始叫 6to5,意为 es6 转 es5。随着 es 标准的演进,有了 es7、es8 等, 6to5 的名字已经不合适了,所以改名为了 babel。

2. 有什么用途 ?

转译 esnext、typescript、flow 等到目标环境支持的 js

许多新的语法,目标环境并不支持。Babel 可以基于目标环境支持的语法进行实现,并且还可以把目标环境不支持的 api 进行 polyfill。
babel7 还支持 preset-env,可以指定 targets 来进行按需转换,转换更加的精准,产物更小。

代码的静态分析

对代码进行 parse 后,能够通过 AST 理解代码的意思,然后进行转换生成目标代码,也可以分析代码的信息,从而进行其他的检查。

  • linter 工具就是分析 AST 的结构,对代码规范进行检查。
  • api 文档自动生成工具,可以提取源码中的注释,然后生成文档。
  • type checker 会根据从 AST 中提取的或者推导的类型信息,对 AST 进行类型是否一致的检查,从而减少运行时因类型导致的错误。
  • 压缩混淆工具,这个也是分析代码结构,进行删除死代码、变量名混淆、常量折叠等各种编译优化,生成体积更小、性能更优的代码。
  • js 解释器,除了对 AST 进行各种信息的提取和检查以外,我们还可以直接解释执行 AST。

一些特定用途的转换

babel 作为一个js transpiler,提供了许多 API,用这些 api 可以完成代码到 AST 的 parse,AST 的转换,以及目标代码的生成。开发者可以用它来来完成一些特定用途的转换

  1. 比如函数插桩(函数中自动插入一些代码,例如埋点代码)
  2. 自动国际化
  3. default import 转 named import
  4. 小程序转译工具 taro,也基于 babel 的 api 来实现的

3. Babel 的转译流程

高级语言:有很多用于描述逻辑的语言特性,比如分支、循环、函数、面向对象等,接近人的思维,可以让开发者快速的通过它来表达各种逻辑。比如 c++、javascript。

低级语言:与硬件和执行细节有关,会操作寄存器、内存,具体做内存与寄存器之间的复制,需要开发者理解熟悉计算机的工作原理,熟悉具体的执行细节。比如汇编语言、机器语言。

  1. parse:将源码 parse 成 抽象语法树AST,进行词法分析、语法分析,让计算机能理解源码字符
  2. transform:遍历 AST,进行增删改,加入目标代码
  3. generate: 将转换后的 AST 打印成目标代码,并生成 sourcemap(记录了源码和转换后的代码的对应关系)

3.1 AST

常见的节点

  1. Literal:字面量(StringLiteral、BooleanLiteral、NumberLiteral、RegExpLiteral等等,比如 let name = 'guang'中的'guang')

  2. Identifier:标识符,变量名、属性名、方法名、参数名等都是

  3. Statement:语句,即可以独立执行的单元,如 break(BreakStatement)、条件语句(SwitchStatement)、声明语句

  4. Declaration:声明语句,它的执行逻辑是在作用域中声明一个变量、函数、class、export、import

  5. Expression:表达式,区别于statement的特点是执行完后有值

  6. Class:整个 class 的内容是 ClassBody,属性是 ClassProperty,方法是ClassMethod(通过 kind 属性来区分是 constructor 还是 method)

  7. Moudules:es module 是语法级别的模块规范,所以也有专门的 AST 节点

  8. import: image.png

  9. export: image.png

  10. Program & Diretive:program 是代表整个程序的节点,它有 body 属性代表程序体,存放 statement 数组,就是具体执行的语句的集合。还有 directives 属性,存放Directive 节点,比如"use strict" 这种指令会使用 Directive 节点表示。Program 是包裹具体执行语句的节点,而 Directive 则是代码中的指令部分。

  11. File & Comment:babel 的 AST 最外层节点是 File,它有 program、comments、tokens 等属性,分别存放 Program 程序体、注释、token 等,是最外层节点。注释分为块注释和行内注释,对应 CommentBlock 和 CommentLine 节点。

AST 的公共属性

  • type: AST 节点的类型
  • start、end、loc:start 和 end 代表该节点对应的源码字符串的开始和结束下标,不区分行列。而 loc 属性是一个对象,有 line 和 column 属性分别记录开始和结束行列号。
  • leadingComments、innerComments、trailingComments: 表示开始的注释、中间的注释、结尾的注释
  • extra:额外信息,用于处理一些特殊情况。比如 StringLiteral 修改 value 只是值的修改,而修改 extra.raw 则可以连同单双引号一起修改。

可视化查看AST节点:astexpoler.net

API