babel-traverse API 及使用 demo [未完成]

161 阅读3分钟

1. 父节点相关

  1. 从当前节点的父节点(不包括当前节点自己)开始向上查找并调用 callback,如果 callback 返回一个真值,那么返回那个父节点;都没有找到,返回 null。
findParent(callback): ?NodePath
  1. findParent,唯一的区别是从当前节点(包括自己)开始查找。
find(callback): ?NodePath
  1. 找到满足 callback 的函数父节点。
getFunctionParent(callback): ?NodePath
  1. 向上遍历节点树,直到命中一个处于list中的父节点。
getStatementParent(): NodePath
getEarliestCommonAncestorFrom(
  paths: Array<NodePath>,
): NodePath
getDeepestCommonAncestorFrom(
  paths: Array<NodePath>,
  filter?: Function,
): NodePath
getAncestry(): Array<NodePath>

判断当前的path是否是maybeDescendant的祖先节点。

isAncestor(maybeDescendant: NodePath): boolean

判断当前的path是否是maybeAncestor的后代。

isDescendant(maybeAncestor: NodePath): boolean

向上查找,直到一个节点的type在提供的type列表中为止,此时返回 ture,否则 false。

inType(): boolean

2. 兄弟节点相关

  1. 得到一个对立的节点。
getOpposite(): ?NodePath
  1. 得到一个完整到的记录。
getCompletionRecords(): Array  
  1. 根据key得到一个兄弟节点。
// key: 即为path.key
getSibling(key): NodePath
  1. 得到当前节点的前一个节点。
getPrevSibling(): NodePath
  1. 得到当前节点的下一个节点。
getNextSibling(): NodePath
  1. 根据字符串路径得到一个节点,类似于lodash中的get方法:path.get('body.0')
getAllNextSiblings(): Array<NodePath>
getAllPrevSiblings(): Array<NodePath>
get(
  key: string,
  context?: boolean | TraversalContext,
): NodePath
  1. 获取绑定的标示,如:
getBindingIdentifiers(duplicates?): Object
var a = 1, { d } = b, [c] = e
//       ⬇
//
{ a:
   Node {
     type: 'Identifier',
     start: 4,
     end: 5,
     loc:
      SourceLocation { start: [Position], end: [Position], identifierName: 'a' },
     name: 'a' },
  d:
   Node {
     type: 'Identifier',
     start: 27,
     end: 28,
     loc:
      SourceLocation { start: [Position], end: [Position], identifierName: 'd' },
     name: 'd' },
  b:
   Node {
     type: 'Identifier',
     start: 15,
     end: 16,
     loc:
      SourceLocation { start: [Position], end: [Position], identifierName: 'b' },
     name: 'b' } }
  1. 获取函数外层绑定的标识符,如:
getOuterBindingIdentifiers(duplicates?): Object
function f () {}
// 
//
{ f:
   Node {
     type: 'Identifier',
     start: 43,
     end: 44,
     loc:
      SourceLocation { start: [Position], end: [Position], identifierName: 'f' },
     name: 'f' } }
getBindingIdentifierPaths((duplicates = false), (outerOnly = false))
getOuterBindingIdentifierPaths(duplicates?)

3. 当前节点自身相关

matchesPattern(
  pattern: string,
  allowPartial?: boolean,
): boolean
  1. 别名:is
has(key): boolean
  1. has的否定操作。
isnt(key): boolean
  1. 检查当前节点的key是否等于给定的value
equals(key, value): boolean
isNodeType(type: string): boolean
canHaveVariableDeclarationOrExpression()
canSwapBetweenExpressionAndStatement(replacement)
isStatic()
isCompletionRecord(allowInsideFunction?)
isStatementOrBlock()
referencesImport(moduleSource, importName)
  1. 获取当前节点的 souce 内容。
getSource()
willIMaybeExecuteBefore(target)
resolve(dangerous, resolved)
isConstantExpression()

判断一个模块或者函数是否处于严格模式。
ES6 模块默认是处于严格模式,其实情况看是否使用use strict指令。

isInStrictMode()

4. 修改当前节点相关

  1. 在当前节点的前面插入节点。
insertBefore(nodes)
  1. 在当前节点的后面插入节点。
insertAfter(nodes)
updateSiblingKeys(fromIndex, incrementBy)
unshiftContainer(listKey, nodes)
  1. nodes放入到指定的listKey容器中,如:
// listKey: path.listKey => "body" | "params"
pushContainer(listKey, nodes)
function test(a) {}
path.pushContainer('params', t.identifier('b'))
// ⬇
function test(a, b) {}

path.pushContainer('body', t.expressionStatement(t.identifier('b')))
// ⬇
function test(a) {
  b
}
hoist((scope = this.scope))

5. 删除当前节点相关

remove()

6. 替换当前节点相关

  1. 用多个节点替换当前节点。
replaceWithMultiple(nodes: Array<Object>)
  1. 不推荐使用
    replacement作为一个表达式去解析,然后用解析的结果替换当前节点。
replaceWithSourceString(replacement)
  1. 用一个节点替换当前节点。
replaceWith(replacement)
replaceExpressionWithStatements(nodes: Array<Object>)
replaceInline(nodes: Object | Array<Object>)

7. 注释相关

shareCommentsWithSiblings()
addComment(type: string, content: string, line?: boolean)
addComments(type: string, comments: Array)

8. 上下文相关

维护TraversalContext相关的方法。

call(key): boolean
isBlacklisted(): boolean
visit(): boolean
skip()
skipKey(key)

停止继续往上或者往下遍历一个节点

stop()
setScope()
setContext(context)
resync()
popContext()
pushContext(context)
setup(parentPath, container, listKey, key)
setKey(key)
requeue((pathToQueue = this))

9. 节点类型转化

将可以转化的节点(函数,for 循环等)转换成块节点,如:() => true => () => { return true }

ensureBlock()

将一个箭头函数转化为 ES5 的函数表达式。

arrowFunctionToExpression(
  ({ allowInsertArrow = true, specCompliant = false } = {})
)

参考链接

babel-traverse API

Babel 插件:30分钟从入门到实战