codemod 从 ForInStatement 到 ForStatement
codemod from ForInStatement to ForStatement
我有一个 codemod,我想在其中进行转换
for (var key in foo){}
进入
for (var keys = 0; key < foo; key++){}
我做到了这一点:
return j(file.source)
.find(j.ForInStatement)
.replaceWith(p => {
var prop = p.node.left.declarations[0].id;
var v = [j.variableDeclarator(prop, null)];
var varDec = j.variableDeclaration('var', v);
var binary = j.binaryExpression('<', prop, j.identifier('foo'));
var uE = j.updateExpression('++', prop, false);
var block = j.blockStatement([]);
var forIn = j.forStatement(varDec, binary, uE, block);
return forIn;
})
.toSource();
for (var key; key < foo; key++)
{}
我仍然对从头开始创建东西有些迷茫...
问题:
- 我这样做正确吗?感觉很冗长,但也许这是要走的路。
- 如何完成?例如,我缺少
foo.length
...
PS: Felix,如果您正在阅读本文,请指出我可以在哪里发送拉取请求以改进文档!在我尝试学习这个 API 时,我很乐意提供帮助。哦,还有 Felix,你们制作的工具真棒!
直接创建AST节点确实比较冗长。但是,jscodeshift 导出了一些帮助程序 "methods",允许您从字符串生成 AST 节点并插入现有的 AST 节点(标记模板 ftw!)。
你上面的例子可以简化为:
return j(file.source)
.find(j.ForInStatement)
.replaceWith(p => {
var prop = p.node.left.declarations[0].id;
return statement`for (var ${prop} = 0; ${prop} < foo.length; ${prop}++) ${p.node.body}`;
})
.toSource();
请注意,尽管这些模板方法(expression
、statement
、statements
)有其局限性(您只能插入可以放置标识符的 AST 节点)。
如果您想手动创建 foo.length
,则必须创建 MemberExpression
:
j.memberExpression(
prop,
j.identifier('length')
);
我有一个 codemod,我想在其中进行转换
for (var key in foo){}
进入
for (var keys = 0; key < foo; key++){}
我做到了这一点:
return j(file.source)
.find(j.ForInStatement)
.replaceWith(p => {
var prop = p.node.left.declarations[0].id;
var v = [j.variableDeclarator(prop, null)];
var varDec = j.variableDeclaration('var', v);
var binary = j.binaryExpression('<', prop, j.identifier('foo'));
var uE = j.updateExpression('++', prop, false);
var block = j.blockStatement([]);
var forIn = j.forStatement(varDec, binary, uE, block);
return forIn;
})
.toSource();
for (var key; key < foo; key++)
{}
我仍然对从头开始创建东西有些迷茫...
问题:
- 我这样做正确吗?感觉很冗长,但也许这是要走的路。
- 如何完成?例如,我缺少
foo.length
...
PS: Felix,如果您正在阅读本文,请指出我可以在哪里发送拉取请求以改进文档!在我尝试学习这个 API 时,我很乐意提供帮助。哦,还有 Felix,你们制作的工具真棒!
直接创建AST节点确实比较冗长。但是,jscodeshift 导出了一些帮助程序 "methods",允许您从字符串生成 AST 节点并插入现有的 AST 节点(标记模板 ftw!)。
你上面的例子可以简化为:
return j(file.source)
.find(j.ForInStatement)
.replaceWith(p => {
var prop = p.node.left.declarations[0].id;
return statement`for (var ${prop} = 0; ${prop} < foo.length; ${prop}++) ${p.node.body}`;
})
.toSource();
请注意,尽管这些模板方法(expression
、statement
、statements
)有其局限性(您只能插入可以放置标识符的 AST 节点)。
如果您想手动创建 foo.length
,则必须创建 MemberExpression
:
j.memberExpression(
prop,
j.identifier('length')
);