js 代码从 jQuery 转换或转换为原生?

js code shift or transformer from jQuery to native?

所以如果我需要像这样更改代码:

var amazed = $(['foo', 'bar']).map(function(i, el){
  return this + '!';
});

变成原生喜欢

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 code shift是否可以用于这种情况,比如将jQuery转换为Native,最终只是:

var amazed = ['foo', 'bar'].map(function(el, i){
  return el + '!';
});

你完全可以为此使用 jscodeshift。请注意限制:

  • 并非每个标识符 $ 都可能指代 jQuery。
  • 可能会调用 jQuery 的 .map 函数,看起来像

    var foo = $(['foo', 'bar']);
    foo.map(...);
    

    你可能听不懂。

但是,这些可能不是您的代码库中的问题。编写通用代码模块很难(呃)。编写适用于您的特定代码库的代码更容易。

我会:

查找所有 CallExpressioncalleeMemberExpression MemberExpression 具有 map作为其 属性 和 $(...) 作为其对象。您还可以验证传递给 $ 的参数是否为数组文字。那将再次具有它不会考虑 var foo = []; $(foo);.

的限制

然后你可以用它的参数替换"inner" 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();

https://astexplorer.net/#/kQICtMfd89