国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

使用 jsinspect 檢測前端代碼庫中的重復(fù)/近似代碼

ZoomQuiet / 832人閱讀

摘要:使用檢測前端代碼庫中的重復(fù)近似代碼從屬于筆者的前端入門與工程實(shí)踐,更多前端相關(guān)學(xué)習(xí)資料推薦閱讀前端每周清單第期學(xué)習(xí)資源,發(fā)布,六問程序員如何成長泛前端知識圖譜。利用對于或者代碼構(gòu)建語法樹,根據(jù)不同的節(jié)點(diǎn)類型,譬如等標(biāo)記相似結(jié)構(gòu)的代碼塊。

使用 jsinspect 檢測前端代碼庫中的重復(fù)/近似代碼 從屬于筆者的 Web 前端入門與工程實(shí)踐,更多前端相關(guān)學(xué)習(xí)資料推薦閱讀前端每周清單第6期:Angular 4.0學(xué)習(xí)資源,Egg.js 1.0發(fā)布,六問CTO程序員如何成長、泛前端知識圖譜(Web/iOS/Android/RN)。

在開發(fā)的過程中我們往往會存在大量的復(fù)制粘貼代碼的行為,這一點(diǎn)在項(xiàng)目的開發(fā)初期尤其顯著;而在項(xiàng)目逐步穩(wěn)定,功能需求逐步完善之后我們就需要考慮對代碼庫的優(yōu)化與重構(gòu),盡量編寫清晰可維護(hù)的代碼。好的代碼往往是在合理范圍內(nèi)盡可能地避免重復(fù)代碼,遵循單一職責(zé)與 Single Source of Truth 等原則,本部分我們嘗試使用 jsinspect 對于代碼庫進(jìn)行自動檢索,根據(jù)其反饋的重復(fù)或者近似的代碼片進(jìn)行合理的優(yōu)化。當(dāng)然,我們并不是單純地追求公共代碼地完全剝離化,過度的抽象反而會降低代碼的可讀性與可理解性。jsinspect 利用 babylon 對于 JavaScript 或者 JSX 代碼構(gòu)建 AST 語法樹,根據(jù)不同的 AST 節(jié)點(diǎn)類型,譬如 BlockStatement、VariableDeclaration、ObjectExpression 等標(biāo)記相似結(jié)構(gòu)的代碼塊。我們可以使用 npm 全局安裝 jsinspect 命令:

Usage: jsinspect [options] 


Detect copy-pasted and structurally similar JavaScript code
Example use: jsinspect -I -L -t 20 --ignore "test" ./path/to/src


Options:

  -h, --help                         output usage information
  -V, --version                      output the version number
  -t, --threshold            number of nodes (default: 30)
  -m, --min-instances        min instances for a match (default: 2)
  -c, --config                       path to config file (default: .jsinspectrc)
  -r, --reporter [default|json|pmd]  specify the reporter to use
  -I, --no-identifiers               do not match identifiers
  -L, --no-literals                  do not match literals
  -C, --no-color                     disable colors
  --ignore                  ignore paths matching a regex
  --truncate                 length to truncate lines (default: 100, off: 0)

我們也可以選擇在項(xiàng)目目錄下添加 .jsinspect 配置文件指明 jsinspect 運(yùn)行配置:

{
  "threshold":     30,
  "identifiers":   true,
  "literals":      true,
  "ignore":        "test|spec|mock",
  "reporter":      "json",
  "truncate":      100,
}

在配置完畢之后,我們可以使用 jsinspect -t 50 --ignore "test" ./path/to/src 來對于代碼庫進(jìn)行分析,以筆者找到的某個(gè)代碼庫為例,其檢測出了上百個(gè)重復(fù)的代碼片,其中典型的代表如下所示。可以看到在某個(gè)組件中重復(fù)編寫了多次密碼輸入的元素,我們可以選擇將其封裝為函數(shù)式組件,將 labelhintText 等通用屬性包裹在內(nèi),從而減少代碼的重復(fù)率。

Match - 2 instances

./src/view/main/component/tabs/account/operation/login/forget_password.js:96,110
return 
{ this.setState({ userPwd: value }) }} />
./src/view/main/component/tabs/my/login/forget_password.js:111,125 return
{ this.setState({ userPwd: value }) }} />

筆者也對于 React 源碼進(jìn)行了簡要分析,在 246 個(gè)文件中共發(fā)現(xiàn) 16 個(gè)近似代碼片,并且其中的大部分重復(fù)源于目前基于 Stack 的調(diào)和算法與基于 Fiber 重構(gòu)的調(diào)和算法之間的過渡時(shí)期帶來的重復(fù),譬如:

Match - 2 instances

./src/renderers/dom/fiber/wrappers/ReactDOMFiberTextarea.js:134,153
  var value = props.value;
  if (value != null) {
    // Cast `value` to a string to ensure the value is set correctly. While
    // browsers typically do this as necessary, jsdom doesn"t.
    var newValue = "" + value;

    // To avoid side effects (such as losing text selection), only set value if changed
    if (newValue !== node.value) {
      node.value = newValue;
    }
    if (props.defaultValue == null) {
      node.defaultValue = newValue;
    }
  }
  if (props.defaultValue != null) {
    node.defaultValue = props.defaultValue;
  }
},

postMountWrapper: function(element: Element, props: Object) {

./src/renderers/dom/stack/client/wrappers/ReactDOMTextarea.js:129,148
  var value = props.value;
  if (value != null) {
    // Cast `value` to a string to ensure the value is set correctly. While
    // browsers typically do this as necessary, jsdom doesn"t.
    var newValue = "" + value;

    // To avoid side effects (such as losing text selection), only set value if changed
    if (newValue !== node.value) {
      node.value = newValue;
    }
    if (props.defaultValue == null) {
      node.defaultValue = newValue;
    }
  }
  if (props.defaultValue != null) {
    node.defaultValue = props.defaultValue;
  }
},

postMountWrapper: function(inst) {

筆者認(rèn)為在新特性的開發(fā)過程中我們不一定需要時(shí)刻地考慮代碼重構(gòu),而是應(yīng)該相對獨(dú)立地開發(fā)新功能。最后我們再簡單地討論下 jsinspect 的工作原理,這樣我們可以在項(xiàng)目需要時(shí)自定義類似的工具以進(jìn)行特殊代碼的匹配或者提取。jsinspect 的核心工作流可以反映在 inspector.js 文件中:

... 
this._filePaths.forEach((filePath) => {
  var src = fs.readFileSync(filePath, {encoding: "utf8"});
  this._fileContents[filePath] = src.split("
");
  var syntaxTree = parse(src, filePath);
  this._traversals[filePath] = nodeUtils.getDFSTraversal(syntaxTree);
  this._walk(syntaxTree, (nodes) => this._insert(nodes));
});

this._analyze();
...

上述流程還是較為清晰的,jsinspect 會遍歷所有的有效源碼文件,提取其源碼內(nèi)容然后通過 babylon 轉(zhuǎn)化為 AST 語法樹,某個(gè)文件的語法樹格式如下:

Node {
  type: "Program",
  start: 0,
  end: 31,
  loc:
   SourceLocation {
     start: Position { line: 1, column: 0 },
     end: Position { line: 2, column: 15 },
     filename: "./__test__/a.js" },
  sourceType: "script",
  body:
   [ Node {
       type: "ExpressionStatement",
       start: 0,
       end: 15,
       loc: [Object],
       expression: [Object] },
     Node {
       type: "ExpressionStatement",
       start: 16,
       end: 31,
       loc: [Object],
       expression: [Object] } ],
  directives: [] }
{ "./__test__/a.js": [ "console.log(a);", "console.log(b);" ] }

其后我們通過深度優(yōu)先遍歷算法在 AST 語法樹上構(gòu)建所有節(jié)點(diǎn)的數(shù)組,然后遍歷整個(gè)數(shù)組構(gòu)建待比較對象。這里我們在運(yùn)行時(shí)輸入的 -t 參數(shù)就是用來指定分割的原子比較對象的維度,當(dāng)我們將該參數(shù)指定為 2 時(shí),經(jīng)過遍歷構(gòu)建階段形成的內(nèi)部映射數(shù)組 _map 結(jié)構(gòu)如下:

{ "uj3VAExwF5Avx0SGBDFu8beU+Lk=": [ [ [Object], [Object] ], [ [Object], [Object] ] ],
  "eMqg1hUXEFYNbKkbsd2QWECLiYU=": [ [ [Object], [Object] ], [ [Object], [Object] ] ],
  "gvSCaZfmhte6tfnpfmnTeH+eylw=": [ [ [Object], [Object] ], [ [Object], [Object] ] ],
  "eHqT9EuPomhWLlo9nwU0DWOkcXk=": [ [ [Object], [Object] ], [ [Object], [Object] ] ] }

如果有大規(guī)模代碼數(shù)據(jù)的話我們可能形成很多有重疊的實(shí)例,這里使用了 _omitOverlappingInstances 函數(shù)來進(jìn)行去重;譬如如果某個(gè)實(shí)例包含節(jié)點(diǎn) abcd,另一個(gè)實(shí)例包含節(jié)點(diǎn)組 bcde,那么會選擇將后者從數(shù)組中移除。另一個(gè)優(yōu)化加速的方法就是在每次比較結(jié)束之后移除已經(jīng)匹配到的代碼片:

_prune(nodeArrays) {
  for (let i = 0; i < nodeArrays.length; i++) {
    let nodes = nodeArrays[i];
    for (let j = 0; j < nodes.length; j++) {
      this._removeNode(nodes[j]);
    }
  }
}

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/82229.html

相關(guān)文章

  • JavaScript權(quán)威指南筆記(上)-語言核心

    摘要:二進(jìn)制浮點(diǎn)數(shù)和四舍五入錯(cuò)誤在使用實(shí)數(shù)時(shí),常常只是真實(shí)值的一個(gè)近似表示。作用域分類全局函數(shù),塊級作用域鏈變量對象用于存儲執(zhí)行上下文中的變量函數(shù)聲明函數(shù)參數(shù)變量初始化階段瀏覽器截圖瀏覽器截圖代碼執(zhí)行階段類和模塊 詞法結(jié)構(gòu) 字符集 使用Unicode編寫 ES3 Unicode2.1+ ES5 Unicode3+ 區(qū)分大小寫 注釋 // 注釋 /* 注釋 */ 標(biāo)識符和保留字 必須以字...

    skinner 評論0 收藏0
  • 咋做長文本去重

    摘要:新問題拋出有沒有一種簽名算法,如果文本非常相似,簽名值也非常相似呢二文本相似性的簽名算法上文提出的問題,可以用局部敏感哈希解決,局部敏感哈希是一類文本越相似,哈希值越相似的算法,有興趣的同學(xué)自行百度,這里分享一下的思路。 緣起:(1)原創(chuàng)不易,互聯(lián)網(wǎng)抄襲成風(fēng),很多原創(chuàng)內(nèi)容在網(wǎng)上被抄來抄去,改來改去(2)百度的網(wǎng)頁庫非常大,爬蟲如何判斷一個(gè)新網(wǎng)頁是否與網(wǎng)頁庫中已有的網(wǎng)頁重復(fù)呢?這是本文要...

    coordinate35 評論0 收藏0
  • 算法分析 - Algorithms, Part I, week 1 ANALYSIS OF ALGO

    摘要:實(shí)際上這個(gè)情形中存在冪定律實(shí)際上絕大多數(shù)的計(jì)算機(jī)算法的運(yùn)行時(shí)間滿足冪定律。基于研究得知,原則上我們能夠獲得算法,程序或者操作的性能的精確數(shù)學(xué)模型。 前言 上一篇:并查集下一篇:棧和隊(duì)列 在算法性能上我們常常面臨的挑戰(zhàn)是我們的程序能否求解實(shí)際中的大型輸入:--為什么程序運(yùn)行的慢?--為什么程序耗盡了內(nèi)存? 沒有理解算法的性能特征會導(dǎo)致客戶端的性能很差,為了避免這種情況的出線,需要具備算法...

    Leo_chen 評論0 收藏0
  • JavaScript 工作原理之三-內(nèi)存管理及如何處理 4 類常見的內(nèi)存泄漏問題(譯)

    摘要:這是因?yàn)槲覀冊L問了數(shù)組中不存在的數(shù)組元素它超過了最后一個(gè)實(shí)際分配到內(nèi)存的數(shù)組元素字節(jié),并且有可能會讀取或者覆寫的位。包含個(gè)元素的新數(shù)組由和數(shù)組元素所組成中的內(nèi)存使用中使用分配的內(nèi)存主要指的是內(nèi)存讀寫。 原文請查閱這里,本文有進(jìn)行刪減,文后增了些經(jīng)驗(yàn)總結(jié)。 本系列持續(xù)更新中,Github 地址請查閱這里。 這是 JavaScript 工作原理的第三章。 我們將會討論日常使用中另一個(gè)被開發(fā)...

    weknow619 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<