函数的抽象语法树
1 | function add(a, b){ |
- 代码块是一个
FunctionDeclaration
(函数定义)对象 - 分为3块:
- 一个 id,即 add
- 两个 params,即[a, b]
- 一个 body,即 {return a + b}
add:
identifier
(标志)对象
1 | { |
params:
identifier 数组
1 | [ |
body
BlockStatement
(块状域)对象,即 {return a + b}
ReturnStatement
(Return 域)对象,即 return a + b
argument:BinaryExpression
(二项式)对象,即 a + b
left
:identifier aright
:identifier boperator
: +
抽象语法树 JSON
1 | { |
recast 螺丝刀
npm i recast -g
astexplorer
词法分析
扫描 scanner
按照预定的规则合并成一个个 tokens 列表,会移除空白符、注释等
语法分析
解释器
将词法分析出来的数组转换成 树
,验证语法
解析器 100% 覆盖所有代码结构生成树叫做 CST(具体语法树),AST 不是 100% 与源码匹配
代码转换之babel
解析(parsing) — 将代码字符串转换成 AST抽象语法树
转译(transforming) — 对抽象语法树进行变换操作
生成(generation) — 根据变换后的抽象语法树生成新的代码字符串
操作 AST 重要模块,babel 核心
esprima、estraverse、escodegen
- esprima 将 js 转换成 AST
1 | const esprima = require('esprima') |
- estraverse 遍历和修改 AST
1 | const esprima = require('esprima') |
- escodegen 将 AST 转换成 js
1 | const escodegen = require('escodegen') |
实现语法转换(babel-core、babel-types)
主要依赖esprima、estraverse、escodegen
plugin-transform-arrow-functions
将箭头函数转换 ES5 语法的函数表达式
1 | const babel = require('babel-core') |
babel-code 的 transform(codeString,plugins)
方法将 AST 转换成代码块
codeString:转换前的代码块字符串
plugins:配置项,值为数组,存储修改 babel-code 转换的AST的插件
transform 方法将旧的 AST 处理成新的代码块,返回一个 对象.code
为转换后的代码块字符串
plugins:插件方法必须含有 visitor
属性(固定),值为对象,用于存储修改语法树的方法,方法名严格按照 API
types.functionExpression(null, params, body, false, false
):函数名,函数参数(必填)、函数体(必填)、是否generator函数(默认false)、是否为async函数(默认false)
plugin-transform-classes
将 ES6 class 类转换成 ES5 构造函数
[JSCodeshift]
jscodeshift是一个跑codemods的工具。codemod是一段描述AST要转化成什么样的代码。
Prettier
node 类型
(parameter) node:
Identifier | 标识符
SimpleLiteral |
RegExpLiteral |
Program | 程序
FunctionDeclaration | 函数声明
FunctionExpression | 函数表达式
ArrowFunctionExpression | 箭头函数表达式
SwitchCase | switch
CatchClause | case
VariableDeclarator | 可变说明符
ExpressionStatement | 表达式
BlockStatement | 块
EmptyStatement | 空
DebuggerStatement | 调试
WithStatement | with
ReturnStatement | 返回值
LabeledStatement |
BreakStatement | break
ContinueStatement | continus
IfStatement | if
SwitchStatement |
ThrowStatement | throw
TryStatement | try
WhileStatement | while
DoWhileStatement | dowhile
ForStatement | for
ForInStatement | for in
ForOfStatement | for of
VariableDeclaration |
ClassDeclaration | class
ThisExpression | this
ArrayExpression | array
ObjectExpression | object
YieldExpression | yield
UnaryExpression | 一元
UpdateExpression |
BinaryExpression | 二元
AssignmentExpression | 赋值
LogicalExpression | 逻辑
MemberExpression | 成员
ConditionalExpression | 条件
SimpleCallExpression |
NewExpression | new
SequenceExpression | 序列
TemplateLiteral | 模板
TaggedTemplateExpression |
ClassExpression |
MetaProperty |
AwaitExpression | await
Property |
AssignmentProperty |
Super |
TemplateElement |
SpreadElement |
ObjectPattern | 对象模式
ArrayPattern | 数组模式
RestElement |
AssignmentPattern |
ClassBody | 类主题
MethodDefinition | 方法定义
ImportDeclaration |
ExportNamedDeclaration |
ExportDefaultDeclaration |
ExportAllDeclaration |
ImportSpecifier |
ImportDefaultSpecifier |
ImportNamespaceSpecifier |
ExportSpecifier
用途
代码语法检查,风格检查,代码格式化,高亮,错误提示,自动补全等
JSLint、IDE功能代码压缩
UglifyJS2优化代码
CommonJS、AMD、CMD代码规范转换
CoffeeScript、TypeScript、JSX转换为原生JS