探索AST
AST是什么?
AST全称是Abstract Syntax Tree,翻译过来是抽象语法树的意思。
AST是源代码语法结构的一种抽象表示。它以树状的形式表现编程语言的语法结构,树上的每个节点都表示源代码中的一种结构。 AST维基百科
AST结构是什么样的?
从上面的解释中我们知道了AST是从源代码中分析出来的,那么我们现在可以以一小段代码为例子,看一下AST结构是什么样子的,我们可以打开这个网站 AST在线预览 ,来帮助我们查看一下这段代码具体的AST结构。这里选择了@babel/parser对代码进行了解析。
?栗子:简单的console.log
console.log('hello world');
?分析:console.log的AST
我们可以看到,console.log解析出来的AST其实是一个对象,我们把这个对象一层层展开后,神奇地在
body -> ExpressionStatement -> expression -> callee
里面发现了object(console)和property(log)这两个属性节点。
简单树图如下:
这个对象上还包含了其他很多的属性,其他属性的意思也可以参照下 AST对象文档 上的解释。
AST能做什么?
那如果AST是对象的话,是不是可以通过对象解构的形式把console和log提取出来呢?那既然都可以获取到节点了,是不是也可以给源码加上一些其他操作?
所以可以利用AST来写一个webpack loader或plugin来对源代码做一些预处理。
常见的AST场景就比如通过bable对代码进行转换遍历,删除代码中未被使用过的变量
,删除console.log
,antd的组件按需加载(babel-plugin-import)
,语法高亮
等等,实际这背后都是是在对JavaScript的抽象语法树进行遍历操作,再返回操作后生成的新的AST树。
补充:源代码执行过程
词法分析(token)
因为JS引擎执行代码是从上到下,从左往右扫码执行代码的,编译的第一个阶段是扫描源代码文本,scanner会从左到右扫描文本,把文本拆成一些单词。然后,这些单词传入分词器,经过一系列的识别器(关键字识别器、标识符识别器、常量识别器、操作符识别器等),确定这些单词的词性,这一过程的产物是token序列。token序列用<type, value>来表示,type表示一个单词种类,value为属性值。
console.log(‘hello world’)的词法分析token如下:
语法分析(AST)
语法分析个人理解就是在收集了词法分析的基础上,对JS的文法规则(rules of grammar)
输出AST抽象解析树,《语法命名规则参考》,
另外这棵树是可以任意遍历和增删改查的,因为这棵树是生成在编译成计算机识别的代码之前的。
总结
现在对源代码的解析到运行有了一些基本理解,那么我们可以尝试着写一个简单的webpack loader或plugin实践下,理解源码的执行或直接对其中做一些特定的干预过程:
parser(解析) -> traverse(遍历/增删改查) -> generate(生成)