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

js code shift or transformer from jQuery to native?

本文关键字:代码 原生 原生代 jQuery js 转换      更新时间:2023-09-26

因此,如果我需要更改这样的代码:

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代码移位可以用于这种情况吗,比如将jQuery转换为Native,最终只是:

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

您可以绝对使用jscodeshift。只需注意限制:

  • 并不是每个标识符$都可能引用jQuery
  • 可能有对jQuery的.map函数的调用看起来像

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

    你可能抓不到。

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

我会以下:

查找calleeMemberExpression的所有CallExpressionMemberExpressionmap为其属性,以$(...)为其对象。您还可以验证传递给$的参数是否为数组文字。这将再次具有它不会考虑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();

https://astexplorer.net/#/kQICtMfd89