所以,如果我需要更改这样的代码:
var amazed = $(['foo', 'bar']).map(function(i, el){
return this + '!';
});
进入Native就像
var amazed = (['foo', 'bar']).map(function(el, i){
return el + '!';
});
我可以做(https://astexplorer.net/#/0rIHMowCQf)
之类的事情 return j(file.source)
.find(j.Identifier).filter(ident => {
if (ident.node.name == '$') console.log(ident);
return ident.node.name == '$';
}).replaceWith('').toSource();
作为第一步,将删除jQuery $
符号并留下可以正常工作的()
,但感觉我在作弊,因为我只是给CallExpression一个空标识符。我仍然需要发现如何替换参数的顺序。
可以将js代码转换用于此类情况,例如将jQuery转换为Native,最终只是:
var amazed = ['foo', 'bar'].map(function(el, i){
return el + '!';
});
答案 0 :(得分:2)
你可以绝对使用jscodeshift。请注意这些限制:
$
都可以引用jQuery。可能会调用jQuery的.map
函数,看起来像
var foo = $(['foo', 'bar']);
foo.map(...);
你可能无法捕获。
但是,这些可能不是您的代码库中的问题。编写通用codemod很难(呃)。编写适合您特定代码库的代码更容易。
我想要以下内容:
查找CallExpression
为callee
且 MemberExpression
MemberExpression
作为其属性map
的所有$(...)
个$
{1}}作为其对象。您还可以验证传递给var foo = []; $(foo);
的参数是否为数组文字。这将再次具有不考虑CallExpression
的限制。
然后你可以用它的参数替换“内部” return j(file.source)
.find(j.CallExpression, {
callee: {
property: {
name: 'map'
},
// verify that we call map on $(...)
object: {
callee: {
name: '$',
},
// verify that the argument is an array literal
arguments: {
0: {
type: 'ArrayExpression'
}
},
}
},
})
.forEach(path => {
const jQueryArgument = path.node.callee.object.arguments[0];
// replace "inner" CallExpression with argument
path.node.callee.object = jQueryArgument;
// switch callback arguments
var callback = path.node.arguments[0];
callback.params.reverse();
})
.toSource();
。替换回调的函数参数只是为了。
所有这一切。所有检查都是可选的。测试越不严格,您可以覆盖的用例越多,但获得误报的可能性也会越大。
{{1}}