简介
Oast是一款专门用于解析和操作JS AST(抽象语法树)的npm包。AST代表了代码的语法结构,而且被广泛地用于代码编辑器(如VSCode、Atom、Sublime)和代码工具(如Babel、ESLint、Uglify)中。Oast提供了完整的AST节点和一个方便的规则引擎,同时也支持AST操作的可扩展性。
安装和使用
使用npm进行安装:
--- ------- ----
使用NodeJS将JS代码解析成AST对象并编辑:
----- ---- - ---------------- -- ------------- ----- --- - -------------------- ------ - ------ - - -- ---- -- ----------- ------------------ - ----------- ------- - -- ---------- --- ---------------------- - ------------------------ --- ------------ - - --- -- ------------- ----- ---- - ------------------- ------------------ -- --------- ------ - -- ------ - - -- -- --
节点对象
节点通常包含一些元信息(如行号、开始位置、结束位置),并且由AST解析器创建。要访问某个节点的元信息,可以使用node.start和node.end属性。
每个节点都会有一个type属性表示其类型。
让我们看一些基本的节点类型:
Identifier
标识符节点表示变量或函数的名称。
----- --- - ----------------- - - ----- -------------------------------------------- -- ------- ---------- ------ ------------- ----- ---- ------ -- ---- --
Literal
字面量节点表示语言中的常量。
----- --- - ----------------- - - ----- ---------------------------------------------- -- ------- ------- ------ ---------- ------ -- ------ --- ---- ---
BinaryExpression
二元表达式节点表示常见的二元操作(如加减乘除)。
----- --- - ----------------- - - - - ----- ---------------------------------------------- -- ------- ---------------- ------ ------------------- --------- ---- ------ --- ---- ---
ExpressionStatement
表达式语句节点表示表达式组成的语句,如赋值语句、调用语句等。
----- --- - ------------- - - - ----- ------------------------- -- ------- ------------------- ------ ---------------------- ----------- -----------------
属性访问
访问AST节点对象的属性,你可以使用以下两种方式:
- 直接访问节点对象的属性:比如
node.property
或node.body.body[0]
- 使用遍历方法:如
oast.traverse()
或oast.traverseTree()
对AST树进行遍历
遍历方法需要第二个参数作为代表访问节点的函数:
------------------ - ----------- ------- - ----------------------- - ---
这个例子会遍历AST树,并且使用函数enter()
得到每个节点对象。你会发现这个函数在遍历阶段会重复地调用多次,因为它将为每个节点调用一次。
相似地,oast.traverseTree()
遍历的时候也可以返回父对象:
---------------------- ------ ------- -- - ---------------------- ------ -- ------------- ---
节点操作
在操作AST树之前,你要知道以下这些有用的函数:
oast.buildNode(type, props)
这个函数可以帮助你构建一个节点对象,它接受一个AST节点类型和一个包含该节点类型的属性的对象。
----- ---- - ---------------------------- ------ -------------
oast.append(parent, node)
添加一个节点,将其作为子节点连接到父节点中。
----- ---- - ------------------------------------- ------ ---------- ------------------------ ------
oast.insert(parent, node, index)
添加一个节点,将其作为子节点连接到父节点中,将其插入在子节点数组中的指定位置。
----- ---- - ------------------------------------- ------ ---------- --------------------- ----- ---
oast.replace(parent, node, newNode)
替换一个节点,将其替换为另一个节点。注意,这个函数不会修改原对象,而是返回一个新的节点对象。
----- --------- - ----------------------------------- ----- --------- - --------------------------------- ----- ------ - ----------------- ---------- -----------
oast.remove(parent, node)
删除一个节点,可以将其从父节点中分离并返回,或者你可以传递一个true
参数,以仅仅分离节点。
-- ------ --- ------ ----- ------ - --------------------------------- ----- ------- - ---------------- -------- -- ---- ------ ---------------- ------- ------
规则引擎
规则引擎是Oast的一个方便功能。它可以让你创建一组规则以操作AST树,如遍历、过滤、添加、编辑等。你可以使用createRule()
函数建立规则:
----- ---- - ----------------- ----------- ------- --- ----------- ------- -- --- -------------------- -----
请注意,createRule()
创建一个规则对象,它有两个函数:enter()
和leave()
,在每个节点进入和离开时调用。这些函数都有两个参数:节点本身和它的父节点。在调用这些函数时,当前节点的子节点还没有被访问并扫描。因此,你可以使用规则引擎来进行许多操作:
-- -------------- ----- ------ - ----------------- ----------- ------- - -- ---------- --- ----------------- - ------------------- --- ------------ - - --- ---------------------- -----
skip()
通过skip()
函数让规则引擎跳过当前节点并遍历它的子节点。
----- ------ - ----------------- ----------- ------- - -- ---------- --- -------------- - ------------ ----------------------- - - --- ---------------------- -----
这个例子中,当访问IfStatement
节点时会使用skip()
函数跳过它,防止它被规则引擎访问两次。
remove()
通过remove()
函数从AST树中删除节点。
----- ------ - ----------------- ----------- ------- - -- ---------- --- ----------------- - ------------------- ------ - - --- ---------------------- -----
这个例子中,当访问BlockStatement
节点时,会删除它并将其从当前节点的子节点中删除。
总结
Oast是一个出色的工具,可以用于操作AST。它可以轻松地构建、操作和遍历AST树,提供了一些有用的函数和规则引擎功能。本教程介绍了节点对象、属性访问和节点操作的基本知识,同时详细展示了它如何在实际场景中使用。
来源:JavaScript中文网 ,转载请联系管理员! 本文地址:https://www.javascriptcn.com/post/60066f953d1de16d83a66ce6