Babel 小技巧

执行 path

使用 path.evaluate() ,返回的 confidenttrue 则表明成功执行,value 为返回值
示例:let { confident, value } = path.evaluate();

同一个函数应用到多种访问节点

使用 | 把需要访问的节点组合起来即可,如

const visitor = {
  'VariableDeclarator|FunctionDeclaration'(path) {}
};

删除无用的空语句

删除空语句 ; ,美化代码
空语句在 AST 中节点为 EmptyStatement ,如可写插件如下

const visitor =
{
  'EmptyStatement'(path) {
    path.remove();
  }
}

查看作用域 scope

path.scope.dump() 即可查看自底向上的作用域

path.scope.dump 源码 如下(dump定义处)

dump() {
    const sep = "-".repeat(60);
    console.log(sep);
    let scope: Scope = this;
    do {
      console.log("#", scope.block.type);
      for (const name of Object.keys(scope.bindings)) {
        const binding = scope.bindings[name];
        console.log(" -", name, {
          constant: binding.constant,
          references: binding.references,
          violations: binding.constantViolations.length,
          kind: binding.kind,
        });
      }
    } while ((scope = scope.parent));
    console.log(sep);
  }

同一节点使用多个函数

示例原始 js 代码

var s = 'hello world';

Babel 插件

function log_a(path) { console.log('This is [a] function -- ' + path.node.init.value); }
function log_b(path) { console.log('This is [b] function -- ' + path.node.init.value); }
function log_c(path) { console.log('This is [c] function -- ' + path.node.init.value); }
const visitor =
{
    'VariableDeclarator': {
        'enter': [log_a, log_c, log_b]
    }
}

请注意!
enter 需为数组!函数执行顺序为列表中函数顺序!

参考链接

重置、更新 scope

处理步骤:在插件节点处理代码末尾添加 path.scope.crawl();
场景:插件使用了 scope 相关,使用了 insert 相关(如insertBefore、insertAfter) …

参考链接


本文会不定期更新

推荐阅读

Table of Contents