So if I would need to change code like this:
所以,如果我需要更改这样的代码:
var amazed = $(['foo', 'bar']).map(function(i, el){
return this + '!';
});
into Native like
像Native一样
var amazed = (['foo', 'bar']).map(function(el, i){
return el + '!';
});
I can do something like (https://astexplorer.net/#/0rIHMowCQf)
我可以做点什么(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();
as a first step and that will delete the jQuery $
sign and just leave a ()
which can work, but feels like I am cheating since I am just giving a empty Identifier to the CallExpression. I still have to discover how to replace the order of the arguments.
作为第一步,将删除jQuery $符号,并留下一个可以工作的(),但感觉我在作弊,因为我只是给CallExpression一个空标识符。我仍然需要发现如何替换参数的顺序。
Can js code shift be used for such cases, like transforming jQuery to Native, and eventually just:
js代码转换可以用于这种情况,比如将jQuery转换为Native,最终只是:
var amazed = ['foo', 'bar'].map(function(el, i){
return el + '!';
});
1 个解决方案
#1
2
You can absolute use jscodeshift for this. Just be aware of the limitations:
你可以绝对使用jscodeshift。请注意以下限制:
- Not every identifier
$
might refer to jQuery. -
There might be calls to jQuery's
.map
function that look like可能会调用jQuery的.map函数
var foo = $(['foo', 'bar']); foo.map(...);
which you probably won't be able to catch.
你可能无法捕捉到它。
并非每个标识符$都可以引用jQuery。
However, these might not be issues in your code base. Writing generic codemods is hard(er). Writing one that works for your specific codebase is easier.
但是,这些可能不是您的代码库中的问题。编写通用codemod很难(呃)。编写适用于特定代码库的代码更容易。
I would to the following:
我想以下几点:
Find all CallExpression
's whose callee
is a MemberExpression
and that MemberExpression
has map
as its property and $(...)
as its object. You can also verify that the argument passed to $
is an array literal. That would again have the limitation that it wouldn't consider var foo = []; $(foo);
.
找到其Callee是MemberExpression的所有CallExpression,并且MemberExpression将map作为其属性并将$(...)作为其对象。您还可以验证传递给$的参数是否为数组文字。这将再次具有不考虑var foo = []的限制; $(富);.
Then you can replace the the "inner" CallExpression
with its argument. Replacing the function parameters of the callback is simply to.
然后你可以用它的参数替换“内部”CallExpression。替换回调的函数参数只是为了。
All of that together. All the checks are optional. The less strict the tests are, the more use cases you can cover, but the possibility for getting false positives will also be larger.
所有这些在一起。所有检查都是可选的。测试越不严格,您可以覆盖的用例越多,但获得误报的可能性也会越大。
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
2
You can absolute use jscodeshift for this. Just be aware of the limitations:
你可以绝对使用jscodeshift。请注意以下限制:
- Not every identifier
$
might refer to jQuery. -
There might be calls to jQuery's
.map
function that look like可能会调用jQuery的.map函数
var foo = $(['foo', 'bar']); foo.map(...);
which you probably won't be able to catch.
你可能无法捕捉到它。
并非每个标识符$都可以引用jQuery。
However, these might not be issues in your code base. Writing generic codemods is hard(er). Writing one that works for your specific codebase is easier.
但是,这些可能不是您的代码库中的问题。编写通用codemod很难(呃)。编写适用于特定代码库的代码更容易。
I would to the following:
我想以下几点:
Find all CallExpression
's whose callee
is a MemberExpression
and that MemberExpression
has map
as its property and $(...)
as its object. You can also verify that the argument passed to $
is an array literal. That would again have the limitation that it wouldn't consider var foo = []; $(foo);
.
找到其Callee是MemberExpression的所有CallExpression,并且MemberExpression将map作为其属性并将$(...)作为其对象。您还可以验证传递给$的参数是否为数组文字。这将再次具有不考虑var foo = []的限制; $(富);.
Then you can replace the the "inner" CallExpression
with its argument. Replacing the function parameters of the callback is simply to.
然后你可以用它的参数替换“内部”CallExpression。替换回调的函数参数只是为了。
All of that together. All the checks are optional. The less strict the tests are, the more use cases you can cover, but the possibility for getting false positives will also be larger.
所有这些在一起。所有检查都是可选的。测试越不严格,您可以覆盖的用例越多,但获得误报的可能性也会越大。
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();