Open pfan123 opened 4 years ago
Babel 是一个工具链,主要用于将 ECMAScript 2015+ 版本的代码转换为向后兼容的 JavaScript 语法,以便能够运行在当前和旧版本的浏览器或其他环境中。 Babel 能帮我们做的的事情:
useBuiltIns
JavaScript 社区其实有非常多 parser 实现,比如 Acorn、Esprima、Recast、Traceur、Cherow 等等。但我们还是选择使用 Babel,主要有以下几个原因:
JavaScript
parser
Acorn
Esprima
Recast
Traceur
Cherow
Babel
TypeScript
Flow
JSX
不管是任意语言的代码,其实它们都有两个共同点
第一点很好理解,既然代码是字符串构成的,我们要修改/编译代码的最简单的方法就是使用字符串的各种正则表达式。例如我们要将 JSON 中一个键名 foo 改为 bar,只要写一个简单的正则表达式就能做到:
JSON
foo
bar
jsonStr.replace(/(?<=")foo(?="\s*:)/i, 'bar')
编译就是把一段字符串改成另外一段字符串。
Babel-core(@babel/core)
@babel/core 功能可以 js 代码转换为 低版本代码 / ast / parse ,方便各个插件分析语法进行相应的处理。有些新语法在低版本 js 中是不存在的,如箭头函数,rest 参数,函数默认值等,这种语言层面的不兼容只能通过将代码转为 ast,分析其语法后再转为低版本 js。
@babel/core
提供 API 方法 transform transformSync transformAsync transformFile transformFileSync transformFromAst transformFromAstSync transformFromAstAsync parse parseSync parseAsync
plugin-transform-runtime(@babel/plugin-transform-runtime)
@babel/plugin-transform-runtime 使用上依赖 @babel/runtime(可以在 @babel/plugin-transform-runtime 包中package.json中查看),babel 编译 es6 到 es5 的过程中,plugin-transform-runtime 为新特性的 API 添加私有 Helper 方法实现非侵入式不污染全局 API, 私有 Helper 方法实现存在 @babel/runtime 中 。
@babel/plugin-transform-runtime
@babel/runtime
提到 plugin-transform-runtime 通常会与 babel-polyfill 对比,babel-polyfill 实现是改 API Prototype 进行实现会造成全局污染,因此开发过程中通常针对第三方模块或者组件库时使用 plugin-transform-runtime,平常的项目使用 babel-polyfill 即可
Babel-parser(@babel/parser)
@babel/parser 就是 Babel 的 parser。它可以把一段符合规范的 JavaScript 代码输出成一个符合 Esprima 规范的 AST。 大部分 parser 生成的 AST 数据结构都遵循 Esprima 规范,包括 ESLint 的 parser ESTree。这就意味着我们熟悉了 Esprima 规范的 AST 数据结构还能去写 ESLint 插件。
@babel/parser
AST
我们可以尝试解析 n * n 这句简单的表达式:
n * n
import * as parser from "@babel/parser"; const code = `n * n` parser.parse(code)
最终 @babel/parser 会解析成这样的数据结构:
结构:
可以使用 ASTExploroer 快速地查看代码的 AST
Babel-traverse (@babel/traverse)
babel-traverse 可以遍历由 Babylon 生成的抽象语法树,并把抽象语法树的各个节点从拓扑数据结构转化成一颗路径(Path)树,Path 表示两个节点之间连接的响应式(Reactive)对象,它拥有添加、删除、替换节点等方法。当你调用这些修改树的方法之后,路径信息也会被更新。除此之外,Path 还提供了一些操作作用域(Scope) 和标识符绑定(Identifier Binding) 的方法可以去做处理一些更精细复杂的需求。可以说 babel-traverse 是使用 Babel 作为编译器最核心的模块。
babel-traverse
尝试一下把一段代码中的 n * n 变为 x * x:
x * x
import * as parser from "@babel/parser"; import traverse from "@babel/traverse"; const code = `function square(n) { return n * n; }`; const ast = parser.parse(code); traverse(ast, { enter(path) { if (path.isIdentifier({ name: "n" })) { path.node.name = "x"; } } })
Babel-types(@babel/types)
babel-types 是一个用于 AST 节点的 Lodash 式工具库,它包含了构造、验证以及变换 AST节点的方法。 该工具库包含考虑周到的工具方法,对编写处理 AST 逻辑非常有用。例如我们之前在 babel-traverse中改变标识符 n 的代码可以简写为:
babel-types
Lodash
发现使用 babel-types能提高我们转换代码的可读性,在配合 TypeScript 这样的静态类型语言后,babel-types 的方法还能提供类型校验的功能,能有效地提高我们转换代码的健壮性和可靠性
babel
Babel 中文网
Babel 用户手册
astexplorer
Babel 是一个 JavaScript 编译器
Babel 是一个工具链,主要用于将 ECMAScript 2015+ 版本的代码转换为向后兼容的 JavaScript 语法,以便能够运行在当前和旧版本的浏览器或其他环境中。 Babel 能帮我们做的的事情:
useBuiltIns
开启JavaScript
社区其实有非常多parser
实现,比如Acorn
、Esprima
、Recast
、Traceur
、Cherow
等等。但我们还是选择使用Babel
,主要有以下几个原因:Babel
可以解析还没有进入 ECMAScript 规范的语法。例如装饰器这样的提案,虽然现在没有进入标准,但是已经广泛使用有一段时间了Babel
提供插件机制解析TypeScript
、Flow
、JSX
这样的JavaScript
超集,不必单独处理这些语言Babel
拥有庞大的生态,有非常多的文档和样例代码可供参考parser
本身,Babel
还提供各种方便的工具库可以优化、生成、调试代码代码的本质
不管是任意语言的代码,其实它们都有两个共同点
第一点很好理解,既然代码是字符串构成的,我们要修改/编译代码的最简单的方法就是使用字符串的各种正则表达式。例如我们要将
JSON
中一个键名foo
改为bar
,只要写一个简单的正则表达式就能做到:编译就是把一段字符串改成另外一段字符串。
Babel
JavaScript
社区其实有非常多parser
实现,比如Acorn
、Esprima
、Recast
、Traceur
、Cherow
等等。但我们还是选择使用Babel
,主要有以下几个原因:Babel
可以解析还没有进入 ECMAScript 规范的语法。例如装饰器这样的提案,虽然现在没有进入标准,但是已经广泛使用有一段时间了Babel
提供插件机制解析TypeScript
、Flow
、JSX
这样的JavaScript
超集,不必单独处理这些语言Babel
拥有庞大的生态,有非常多的文档和样例代码可供参考parser
本身,Babel
还提供各种方便的工具库可以优化、生成、调试代码Babel-core(@babel/core)
@babel/core
功能可以 js 代码转换为 低版本代码 / ast / parse ,方便各个插件分析语法进行相应的处理。有些新语法在低版本 js 中是不存在的,如箭头函数,rest 参数,函数默认值等,这种语言层面的不兼容只能通过将代码转为 ast,分析其语法后再转为低版本 js。plugin-transform-runtime(@babel/plugin-transform-runtime)
@babel/plugin-transform-runtime
使用上依赖@babel/runtime
(可以在 @babel/plugin-transform-runtime 包中package.json中查看),babel 编译 es6 到 es5 的过程中,plugin-transform-runtime 为新特性的 API 添加私有 Helper 方法实现非侵入式不污染全局 API, 私有 Helper 方法实现存在@babel/runtime
中 。Babel-parser(@babel/parser)
@babel/parser
就是Babel
的parser
。它可以把一段符合规范的 JavaScript 代码输出成一个符合 Esprima 规范的AST
。 大部分parser
生成的AST
数据结构都遵循 Esprima 规范,包括 ESLint 的parser
ESTree。这就意味着我们熟悉了 Esprima 规范的AST
数据结构还能去写 ESLint 插件。我们可以尝试解析
n * n
这句简单的表达式:最终
@babel/parser
会解析成这样的数据结构:结构:
Babel-traverse (@babel/traverse)
babel-traverse
可以遍历由 Babylon 生成的抽象语法树,并把抽象语法树的各个节点从拓扑数据结构转化成一颗路径(Path)树,Path 表示两个节点之间连接的响应式(Reactive)对象,它拥有添加、删除、替换节点等方法。当你调用这些修改树的方法之后,路径信息也会被更新。除此之外,Path 还提供了一些操作作用域(Scope) 和标识符绑定(Identifier Binding) 的方法可以去做处理一些更精细复杂的需求。可以说babel-traverse
是使用 Babel 作为编译器最核心的模块。尝试一下把一段代码中的
n * n
变为x * x
:Babel-types(@babel/types)
babel-types
是一个用于AST
节点的Lodash
式工具库,它包含了构造、验证以及变换AST
节点的方法。 该工具库包含考虑周到的工具方法,对编写处理AST
逻辑非常有用。例如我们之前在babel-traverse
中改变标识符 n 的代码可以简写为:发现使用
babel-types
能提高我们转换代码的可读性,在配合 TypeScript 这样的静态类型语言后,babel-types
的方法还能提供类型校验的功能,能有效地提高我们转换代码的健壮性和可靠性Other Resources
babel
Babel 中文网
Babel 用户手册
astexplorer