# Babel 设计
Babel 是一个 MonoRepo 项目,组织非常清晰,我们可以对齐模块进行一下分类:
# 核心
# @babel/core (opens new window)
@babel/core 这也是上面说的‘微内核’架构中的‘内核’。对于Babel来说,这个内核主要干这些事情:
- 加载和处理配置(config)
- 加载插件
- 调用 Parser 进行语法解析,生成 AST
- 调用 Traverser 遍历AST,并使用访问者模式应用'插件'对 - AST 进行转换
- 生成代码,包括SourceMap转换和源代码生成
# 核心周边支撑
# @babel/parser (opens new window)
将源代码解析为 AST 就靠它了。 它已经内置支持很多语法. 例如 JSX、Typescript、Flow、以及最新的ECMAScript规范。目前为了执行效率,parser是不支持扩展的,由官方进行维护。如果你要支持自定义语法,可以 fork 它,不过这种场景非常少。
# @babel/traverse (opens new window)
实现了访问者模式,对 AST 进行遍历,转换插件会通过它获取感兴趣的AST节点,对节点继续操作,增加,修改,删除等
# @babel/generator (opens new window)
将 AST 转换为源代码,支持 SourceMap
# 插件设计
分为:
- 语法插件
- 转换插件
- 预定义集合
# 语法插件
@babel/plugin-syntax-*
,上面说了 @babel/parser
已经支持了很多 JavaScript 语法特性,Parser也不支持扩展. 因此plugin-syntax-*
实际上只是用于开启或者配置Parser的某个功能特性
# 转换插件
用于对 AST 进行转换, 实现转换为ES5代码、压缩、功能增强等目的. Babel仓库将转换插件划分为两种(只是命名上的区别)
@babel/plugin-transform-*
:普通的转换插件@babel/plugin-proposal-*
:还在'提议阶段'(非正式)的语言特性, 目前有这些 (opens new window)
# 预定义集合
插件集合
或者分组,主要方便用户对插件进行管理和使用。比如@babel/preset-env
含括所有的标准的最新特性; 再比如@babel/preset-react
含括所有react相关的插件。
其他集合参考:官网 (opens new window)
# 插件辅助开发
# @babel/template (opens new window)
某些场景直接操作AST太麻烦,就比如我们直接操作DOM一样,所以Babel实现了这么一个简单的模板引擎,可以将字符串代码转换为AST。比如在生成一些辅助代码(helper)时会用到这个库
# @babel/types (opens new window)
AST 节点构造器和断言,用于创建、判断 AST 节点。
# @babel/helper-*
辅助代码,单纯的语法转换可能无法让代码运行起来,比如低版本浏览器无法识别class关键字,这时候需要添加辅助代码,对class进行模拟
参考:https://babeljs.io/docs/en/babel-helper-compilation-targets
# 工具
# @babel/cli (opens new window)
CLI工具
# @babel/register (opens new window)
Patch NodeJs 的require方法,支持导入需要Babel处理的JavaScript模块
# @babel/polyfill (opens new window)
从 Babel 7.4.0 开始,这个包已经被弃用,取而代之的是直接包含 core-js/stable
(用于填充 ECMAScript 特性)和 regenerator-runtime/runtime
(需要使用转译的生成器函数)
# @babel/node (opens new window)
Node.js CLI, 通过它直接运行需要 Babel 处理的JavaScript文件
# @babel/code-frame (opens new window)
打印错误代码的位置