jscpd統(tǒng)計(jì)項(xiàng)目中的代碼重復(fù)度使用詳解
前言
當(dāng)一個(gè)項(xiàng)目開發(fā)時(shí)間較長(zhǎng)以后,總會(huì)存在一些重復(fù)的代碼,這就給維護(hù)和擴(kuò)展帶來障礙。
特別是我們的前端項(xiàng)目,多個(gè)項(xiàng)目中都存在一些較相似的功能,這部分之前不少采用復(fù)制粘貼的方式處理。于是為了優(yōu)化前端項(xiàng)目的代碼,最近我們考慮使用代碼重復(fù)度來作為衡量指標(biāo),對(duì)單個(gè)或多個(gè)項(xiàng)目進(jìn)行重復(fù)代碼的統(tǒng)計(jì),并著手重構(gòu)可優(yōu)化的重復(fù)代碼。
而為了統(tǒng)計(jì)項(xiàng)目中是否有代碼重復(fù),我們使用了 jscpd
工具庫(kù),本文將詳細(xì)介紹該工具的使用方法。
jscpd是什么
jscpd是一個(gè)開源的js工具庫(kù),用于檢測(cè)項(xiàng)目的代碼重復(fù)率,針對(duì)復(fù)制粘貼的代碼尤其有效,支持超過150種的源碼文件格式。
我們?cè)谇岸隧?xiàng)目中,無論是原生的javascript、css、html代碼,還是使用typescript、less、vue、react等代碼,都能較好的識(shí)別出項(xiàng)目中的重復(fù)代碼。
當(dāng)然,這里的重復(fù),更多的指代碼完全重復(fù),即代碼行與代碼字符串,都相同。
如何使用它
下面,先看下如何使用它。
安裝
我們先以全局方式,安裝該工具庫(kù):
npm install jscpd -g
安裝成功后,系統(tǒng)就有一個(gè)全局命令 jscpd
,可以查看版本號(hào),當(dāng)前最新版本是 3.5.3
,如下所示:
$ jscpd -V 3.5.3
安裝成功后,我們就可以很方便的使用它。
示例
例如,我們需要統(tǒng)計(jì)一個(gè)文件 app.js
,只需要在文件目錄執(zhí)行以下命令:
jscpd ./app.js
執(zhí)行成功后,在命令行界面會(huì)顯示結(jié)果,如下圖所示:
圖中的內(nèi)容,我們下面一一做個(gè)說明說明:
Clone found (javascript)
顯示找到的拷貝的重復(fù)代碼塊,這里是javascript文件。
并且會(huì)顯示重復(fù)代碼在文件中具體的行數(shù),便于查找。HTML report saved to report\html\
這句話的意思是,會(huì)在文件目錄下輸出對(duì)應(yīng)報(bào)告的html頁(yè)面,一般默認(rèn)是report\html\
目錄下,用于在頁(yè)面中展示結(jié)果。Format
文件格式,這里是javascript
,還可以是typescript
、tsx
等。Files analyzed
已分析的文件數(shù)量,統(tǒng)計(jì)項(xiàng)目中的代碼文件數(shù)。Total lines
所有文件的總行數(shù)。
這里只有一個(gè)文件,總行數(shù)是105行。Total tokens
所有的token數(shù)量。
這里一般以標(biāo)識(shí)符/變量等
、數(shù)字
、字符串
、空格
或符號(hào)
等等作為一個(gè)token
來統(tǒng)計(jì)數(shù)量。
一行代碼一般包含幾個(gè)到幾十個(gè)不等的token數(shù)量。Clones found
找到拷貝的重復(fù)塊數(shù)量。Duplicated lines
重復(fù)的代碼行數(shù),以及占比。
在表格的Total
行里,重復(fù)代碼的占比就是代碼行的重復(fù)度了,這里是18.1%。Duplicated tokens
重復(fù)的token數(shù)量,以及占比。Found 0 clones
找到了1個(gè)重復(fù)塊。Detection time
檢測(cè)耗時(shí)。
由此可知,./app.js
檢測(cè)1個(gè)文件,發(fā)現(xiàn)了1個(gè)重復(fù)快,在總行數(shù)為105行的代碼中,共有19行代碼完全重復(fù),重復(fù)度為 18.1%
。
配置選項(xiàng)
以上示例是比較簡(jiǎn)單的,直接檢測(cè)單個(gè)文件,通過命令行檢測(cè)單個(gè)文件,打印結(jié)果,并默認(rèn)生成report報(bào)告的頁(yè)面。
如果是在當(dāng)前主流的前端項(xiàng)目中,由于很多文件是輔助工具如依賴包、構(gòu)建、文檔等,并不是有效的代碼,需要排除。這種情況下,我們一般使用配置文件的方式,通過選項(xiàng)配置規(guī)范 jscpd
的使用場(chǎng)景。
jscpd
的配置選項(xiàng)可以通過以下兩種方式創(chuàng)建:
- 在項(xiàng)目根目錄下創(chuàng)建配置文件
.jscpd.json
,然后在該文件中增加具體的配置選項(xiàng); - 也可以直接在
package.json
文件中添加
如果項(xiàng)目根目錄下沒有 package.json
文件,可以自行添加一個(gè),然后在該件中個(gè)增加對(duì)應(yīng)的配置。
無論是Vue還是React項(xiàng)目,使用大致都一樣,如下,在 package.json
中增加 jscpd
配置屬性:
"jscpd": { "threshold": 1, "reporters": [ "html", "console" ], "ignore": [ ".git", "node_modules", "public", ".husky" ], "format": ["javascript", "typescript"], "absolute": true }
以上是一個(gè)常用的配置,具體說明:
threshold 表示重復(fù)度的閾值,超過這個(gè)值,就會(huì)打印錯(cuò)誤報(bào)警。
- 如閾值設(shè)為 1,當(dāng)重復(fù)度為18.1%時(shí),會(huì)報(bào)錯(cuò):
ERROR: jscpd found too many duplicates (18.1%) over threshold (1%)
。
雖然報(bào)錯(cuò),但代碼的檢測(cè)仍然會(huì)正常完成。
reporters 表示生成結(jié)果檢測(cè)報(bào)告的方式,一般有以下幾種:
- console:控制臺(tái)打印
- html:創(chuàng)建可訪問的
html
頁(yè)面 - json:輸出
json
格式的文件報(bào)告 - xml:輸出
xml
格式的文件報(bào)告 - csv:輸出
csv
格式的文件報(bào)告 - markdown:輸出
md
格式的文件報(bào)告 - consoleFull:控制臺(tái)完整打印重復(fù)代碼塊
- verbose:控制臺(tái)輸出
debug
信息
ignore
- 檢測(cè)時(shí)會(huì)忽略的文件目錄或文件,用于過濾一些非業(yè)務(wù)代碼,如依賴包、構(gòu)建或靜態(tài)文件等
format
- 需要進(jìn)行重復(fù)度檢測(cè)的源代碼格式,目前支持150多種,我們常用的如
javascript
、typescript
、css
等
absolute
- 在檢測(cè)報(bào)告中使用絕對(duì)路徑
除此以外,還有很多配置屬性,我們這里不在一一介紹。
輸出報(bào)告
上面介紹會(huì)輸出重復(fù)度檢測(cè)報(bào)告,我們?cè)陧?xiàng)目中設(shè)置好配置文件以后,執(zhí)行以下命令:
jscpd ./src -o 'report'
項(xiàng)目中的業(yè)務(wù)代碼,通常會(huì)選擇放在 ./src
目錄下,所以我們可以直接檢測(cè)該目錄。-o 'report'
通過命令行參數(shù),輸出檢測(cè)報(bào)告到項(xiàng)目根目錄下的 report
文件夾中——當(dāng)然也可以自定義目錄,這時(shí)候就會(huì)生成對(duì)應(yīng)的頁(yè)面文件:
如上所示,本質(zhì)上是一個(gè)本地網(wǎng)頁(yè),而且是基于 VUE
框架創(chuàng)建的網(wǎng)頁(yè),可以在瀏覽器訪問查看,界面長(zhǎng)這樣:
從上圖可知,檢測(cè)了149個(gè)文件,其中存在8塊拷貝復(fù)制的代碼,代碼行計(jì)算的重復(fù)度是 1.18%
,非常直觀。
通過生成本地網(wǎng)頁(yè)直接展示所有的檢測(cè)報(bào)告,并且還能查看到重復(fù)的代碼在哪:
上圖可以看到,在兩個(gè) tsx
組件文件中,存在一段重復(fù)的代碼,也標(biāo)識(shí)除了這兩段代碼在文件中具體行數(shù)。
多個(gè)項(xiàng)目
上面介紹的是單個(gè)項(xiàng)目的重復(fù)度檢測(cè),如果有多個(gè)項(xiàng)目,且存在代碼的復(fù)制粘貼現(xiàn)象,也可以通過jscpd工具進(jìn)行檢測(cè)處理。
我們只需要在多個(gè)項(xiàng)目的上層目錄下新建一個(gè) package.json
文件,設(shè)置相應(yīng)的配置選項(xiàng),就能根據(jù)設(shè)置檢測(cè)這些項(xiàng)目間的重復(fù)代碼。這里需要注意的是,一般只需要檢測(cè)業(yè)務(wù)代碼 src
,在配置文件中 ignore
屬性的忽略目錄,需要帶上各項(xiàng)目的項(xiàng)目名稱。
"ignore": [ "project1/.git", "project1/node_modules", "project2/.git", "project2/node_modules" // ... ]
這樣,就能快速檢測(cè)出多個(gè)項(xiàng)目中的重復(fù)代碼,仍然可在命令行輸出基本信息,以及對(duì)應(yīng)的report頁(yè)面報(bào)告。
規(guī)避代碼檢測(cè)
當(dāng)我們使用jscpd執(zhí)行項(xiàng)目的重復(fù)度檢測(cè)時(shí),由于一些重復(fù)代碼可能是必要的,不想檢測(cè),可以使用代碼注釋標(biāo)識(shí)的方式,讓這部分代碼不用檢測(cè)。
在代碼的首尾位置添加相應(yīng)注釋,jscpd:ignore-start
和 jscpd:ignore-end
,包裹代碼即可。
如在js代碼中,可以這樣使用:
/* jscpd:ignore-start */ import { provide, computed, watch, onMounted, defineComponent } from 'vue' import { useStore } from 'vuex' /* jscpd:ignore-end */
在css及各種預(yù)處理中,也是與js中的用法一樣:
/* jscpd:ignore-start */ .content { height: 100vh; width: 100vw; display: flex; justify-content: center; align-items: center; overflow: hidden; } /* jscpd:ignore-end */
如下在html中的使用:
<!-- // jscpd:ignore-start --> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width,, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <!-- // jscpd:ignore-end -->
通過以上注釋標(biāo)識(shí)以后,這部分的代碼就不會(huì)再被統(tǒng)計(jì)為重復(fù)代碼了。
總結(jié)
以上可知,jscpd工具的使用是非常簡(jiǎn)單的,只需要少許配置就能輸出比較直觀的代碼數(shù)據(jù),方便我們統(tǒng)計(jì)代碼的重復(fù)度。
知道了項(xiàng)目中的重復(fù)代碼,給我們優(yōu)化代碼結(jié)構(gòu),提煉代碼邏輯,增強(qiáng)代碼的可維護(hù)性、可擴(kuò)展性和可復(fù)用性方面,都能帶來比較多的好處,研發(fā)效率的提高也是隨之而來的。
但需要知道的是,該工具統(tǒng)計(jì)的都是代碼完全相同情形下的重復(fù),如果有變量名或標(biāo)識(shí)符改動(dòng)的則難以檢測(cè)到,就更別提代碼邏輯上的重復(fù)了。
以上就是jscpd統(tǒng)計(jì)項(xiàng)目中的代碼重復(fù)度使用詳解的詳細(xì)內(nèi)容,更多關(guān)于jscpd統(tǒng)計(jì)代碼重復(fù)度的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
lodash內(nèi)部方法getFuncName及setToString剖析詳解
本篇章我們主要是通過了解lodash里的兩個(gè)內(nèi)部方法getFuncName方法和setToString方法,在實(shí)際開發(fā)中我們也可以借鑒方法的實(shí)現(xiàn)思路,在需要的時(shí)候簡(jiǎn)單封裝一下,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09微信小程序支付之c#后臺(tái)實(shí)現(xiàn)方法
這篇文章主要介紹了微信小程序支付之c#后臺(tái)實(shí)現(xiàn)方法的相關(guān)資料,希望通過本文能幫助到大家,讓大家實(shí)現(xiàn)這樣的功能,需要的朋友可以參考下2017-10-10使用純JavaScript封裝一個(gè)消息提示條功能示例詳解
這篇文章主要為大家介紹了使用純JavaScript封裝一個(gè)消息提示條功能示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-02-02JavaScript的模塊化開發(fā)框架Sea.js上手指南
Sea.js的目的是追求簡(jiǎn)單的代碼書寫和組織方式,Sea.js并沒有過多功能而是主要對(duì)前端程序的部署結(jié)構(gòu)作出約束,下面我們就來看一下JavaScript的模塊化開發(fā)框架Sea.js上手指南:2016-05-05Dragonfly P2P 傳輸協(xié)議優(yōu)化代碼解析
這篇文章主要為大家介紹了Dragonfly P2P 傳輸協(xié)議優(yōu)化代碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-11-11