2016-05-16 27 views
0

所以,如果我需要改變這樣的代碼:js代碼從jQuery代碼轉換或本地?

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的轉換到本機,並最終只是:

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

我不知道答案,但我會謹慎使用這樣的事情沒有靜態分析工具的。 – Paarth

+0

@Paarth檢查下很好的答案,好工具! – Rikard

回答

2

您可以絕對使用jscodeshift這一點。請注意以下限制:

  • 並非每個標識符$都可能指向jQuery。
  • 有可能是jQuery的.map函數調用,看起來像

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

    ,你可能無法趕上。

但是,這些可能不是您的代碼庫中的問題。編寫通用的codemods很難(er)。編寫適用於特定代碼庫的代碼更容易。

我會於以下內容:

找到所有CallExpression的,其calleeMemberExpressionMemberExpression具有map作爲其財產和$(...)作爲它的對象。您還可以驗證傳遞給$的參數是否爲數組文字。這將再次有限制,它不會考慮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

+0

不錯!這個解釋使我更加了解喲,謝謝!有一個缺失的部分:在返回內部重命名jQuery的'this',但你的解釋我自己釘了它:https://astexplorer.net/#/kQICtMfd89/1(再次感謝你!) – Rikard

+0

哎呀,是的,我錯過了。恭喜你弄明白了 :) –