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



我有这个AST资源管理器片段,它几乎可以让我做我想做的事情,那就是打开这个:

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

进入

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

即包装除CCD_ 1之外的所有顶级语句和声明。然而,我的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();
}

明白了。只需使用j.program来放置一个适当的"程序";CCD_ 4中的AST。

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();
}

最新更新