1

我有这个 AST explorer片段,它几乎可以让我做我想做的事,也就是把它变成:

function bar() {return 42;}
var baz = {}
import 'get-outta-here';

进入

import 'get-outta-here';

function wrap() {
  function bar() {return 42;}
  var baz = {}
}();

即包装除那些之外的所有顶级语句和声明import。但是,我的 jscodeshift 转换在某种程度上是错误的,我无法理解。

  • 我可以包装并删除导入,但我不能将它们移到顶部。
  • 我可以将它们移到顶部但不能换行

我怀疑我的包装逻辑是关闭的:root.get().value.program.body听起来很hacky。

export default function transformer(file, api) {
  const j = api.jscodeshift;
  const root = j(file.source);

  const wrapper = j(j.expressionStatement(
        j.callExpression(
          j.functionExpression(
            j.identifier('foo'), [],
            j.blockStatement(root.get().value.program.body)
          ), []), []));
  
  const nodes = root.find(j.ImportDeclaration).nodes();
  root.find(j.ImportDeclaration).remove();

  // wraps, but doesn't re-add the import at top-level
  return wrapper.toSource();
  
  // fails
  // return wrapper.find(j.Statement).at(0).insertBefore(nodes).toSource();
  
  // moves it to the beginning, but no wrap
  return root.find(j.Statement).at(0).insertBefore(nodes).toSource();
}
4

1 回答 1

2

知道了。只需使用j.program将适当的“程序”AST 放入wrapper.

export default function transformer(file, api) {
  const j = api.jscodeshift;
  const root = j(file.source);

  const wrapper = j(
    j.program([
      j.expressionStatement(
        j.callExpression(
          j.functionExpression(
            j.identifier("foo"),
            [],
            j.blockStatement(root.get().value.program.body)
          ),
          []
        ),
        []
      )
    ])
  );

  const imports = root.find(j.ImportDeclaration);
  const nodes = imports.nodes();
  imports.remove();
  return wrapper.find(j.Statement).at(0).insertBefore(nodes).toSource();
}
于 2021-01-29T11:12:13.160 回答