如何在 jscodeshift 中包装除导入之外的所有顶级语句和声明?

Joa*_*ora 4 javascript jscodeshift

我有这个 AST 浏览器片段,它几乎可以让我做我想做的事情,那就是:

function bar() {return 42;}
var baz = {}
import 'get-outta-here';
Run Code Online (Sandbox Code Playgroud)

进入

import 'get-outta-here';

function wrap() {
  function bar() {return 42;}
  var baz = {}
}();
Run Code Online (Sandbox Code Playgroud)

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

  • 我可以包装并删除导入,但无法将它们移动到顶部。
  • 我可以将它们移至顶部但不能包裹

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

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();
}
Run Code Online (Sandbox Code Playgroud)

Joa*_*ora 5

知道了。只需用于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();
}
Run Code Online (Sandbox Code Playgroud)