初探 babel 深入浅出地分析 babel 原理

写代码的时候,我们经常会使用 babel 来进行 polyfill,但是 babel 是怎么做到的呢?这篇文章会对 babel 有一个大概的介绍babel 是啥?babel 的用途js 转译器 转译 esnext、typescript、flow 等到目标环境支持的 js这个是最常用的功能,用来把代码中的 esnext 的新的语法、typescript 和 flow 的语法转成基于目标环境支持的语法的实现,并且还可以把目标环境不支持的 api 进行 polyfill。一些特定用途的代码转换babe
摘要由CSDN通过智能技术生成

写代码的时候,我们经常会使用 babel 来进行 polyfill,但是 babel 是怎么做到的呢?这篇文章会对 babel 有一个大概的介绍

babel 是啥?

babel 的用途

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

这个是最常用的功能,用来把代码中的 esnext 的新的语法、typescript 和 flow 的语法转成基于目标环境支持的语法的实现,并且还可以把目标环境不支持的 api 进行 polyfill。

一些特定用途的代码转换

babel 是一个转译器,暴露了很多 api,用这些 api 可以完成代码到 AST 的 parse,AST 的转换,以及目标代码的生成

开发者可以用它来来完成一些特定用途的转换,比如函数插桩(函数中自动插入一些代码,例如埋点代码)、自动国际化、default import 转 named import 等。

现在比较流行的小程序转译工具 taro,就是基于 babel 的 api 来实现的。

代码的静态分析

对代码进行 parse 之后,能够进行转换,是因为通过 AST 的结构能够理解代码。理解了代码之后,除了进行转换然后生成目标代码之外,也同样可以用于分析代码的信息,进行一些检查。

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

babel 是转译器还是编译器?

先说结论babel 是转译器

来解释一下为什么,编译指的是将一种编程语言转成另一种编程语言,主要是高级语言到低级语言的转换。

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

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

一般编译器 Compiler 是指高级语言到低级语言的转换工具,对于高级语言到高级语言的转换工具,被叫做转译器 (Transpiler),转译器是一种 source-to-source 的 Compiler。

babel 就是一个 Javascript Transpiler。

babel 的原理

在解释这个问题之前,我们需要了解几个概念

AST:抽象语法树,它以树状的形式表现编程语言的语法结构,树上的每个节点都表示源代码中的一种结构。不同的语言生成 AST 规则不同,在 JS 中,AST 就是一个用于描述代码的 JSON 串

token:指语言中不可再分的最小的单词。如 JS 中的 let、const 等

sourcemap:源码映射,记录了源码到目标代码的转换关系,通过它我们可以找到目标代码中每一个节点对应的源码位置。

babel 是 source-to-source 的转换,整体编译流程分为三步:

  • parse(解析):通过 parse 把源码转换成 AST
  • transform(转换):遍历 AST,调用各种 transform 插件对 AST 进行增删改
  • generate(生成):将转换后的 AST 转换成字符串形式的代码,并生成 sourcemap

parse(解析)

首先 babel 解析源代码生成 AST,那么为什么要生成 AST 呢

首先 AST 省略了一些无意义的分隔符,如;{ }等,分析一个 AST 和直接分析源码相比,肯定是分析 AST 简单

其次,生成了 AST 之后,之后就可以通过修改 AST 来修改代码,为之后的 transform 和 generate 流程提供了便利

生成 AST 的过程分为词法分析和语法分析

词法分析就是把源码分为一个个的 token,而语法分析就是将 token 根据不同的语法结构生成 AST

transform(转换)

transform 阶段会对 parse 生成的 AST 进行处理,使 AST 符合目标环境的 js 代码规范

babel 会对 AST 进行遍历,遍历的过程中处理到不同的 AST 节点会调用注册的相应的 visitor 中的函数,visitor 中的函数可以对 AST 节点进行增删改,返回新的 AST(可以指定是否继续遍历新生成的 AST)。这样遍历完一遍 AST 之后就完成了对代码的修改。

当 Babel 处理一个节点时,是以访问者的形式获取节点信息,并进行相关操作,这种方式是通过 visitor(访问者)对象来完成的

generate(生成)

generate 阶段把最终(经过一系列转换之后)的 AST 转换成目标代码,同时还会创建 sourcemap

babel 会深度优先遍历整个 AST,然后构建可以表示转换后代码的字符串。

AST

AST 也是有标准的,JS parser 的 AST 大多是 ESTree 标准,从 SpiderMonkey 的 AST 标准扩展而来。

Babel 使用一个基于

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值