如何保證前端項目代碼質量
What
什么是代碼本身的質量?
代碼本身的質量: 包括復雜度, 重復率, 代碼風格等。
復雜度: 項目代碼量,模塊大小,耦合度等
重復率: 重復出現的代碼區塊占比,通常要求在5%以下(借助平臺化工具如Sonar)
代碼風格: 代碼風格是否統一(動態語言代碼如JS, Python風格不受約束)
代碼質量下降惡性循環
常見的代碼質量下降的原因:
破罐破摔: 在爛代碼上迭代代碼罪惡感比較小
傳染性: 不在意代碼質量, 只關注業務的產出
心有余而力不足
常見的導致惡性循環的場景:
-
業務壓力太大
爛代碼產生的常見原因是業務壓力大,導致沒有時間或意愿講究代碼質量。因為向業務壓力妥協而生產爛代碼之后,開發效率會隨之下降,進而導致業務壓力更大,形成一種典型的惡性循環。
-
通過增加人力解決業務壓力
為了應對業務壓力,常見的做法就是向項目中增加人力,但是單純地增加人力的話,會因為風格不一致、溝通成本上升等原因導致爛代碼更多。
那么我們應該如何解決呢?
這是一個長期堅持的過程。
代碼質量管控四個階段
-
規范化
建立代碼規范與Code Review制度
1. [airbnb](https://github.com/airbnb/javascript)
2. [standard](https://github.com/standard/standard)
3. [node-style-guide](https://github.com/felixge/node-style-guide)
4. [google javascript style guide](https://google.github.io/styleguide/jsguide.html)
5. [google html/css style guide](https://google.github.io/styleguide/htmlcssguide.html)
6. [Vue風格指南](https://cn.vuejs.org/v2/style-guide/)
7. 我覺得統一項目目錄結構也是規范化的一種(比如我們用腳手架創建項目模板), 一個規范化的目錄結構大大降低新人的上手成本。
-
自動化
使用工具(linters)自動檢查代碼質量。
-
流程化
將代碼質量檢查與代碼流動過程綁定。
質量檢查與代碼流動綁定后的效果:
備注:
1. 編輯時候: 通過編輯器插件, 實時查看質量檢查
2. 可以利用CI(Jekins/Travis)把構建發布過程搬到線上, 先跑代碼掃描, 測試代碼等, 然后沒有錯誤再進行build, build成功通過ssh推到服務器。
-
中心化
以團隊整體為視角,集中管理代碼規范,并實現質量狀況透明化。
當團隊規模越來越大,項目越來越多時,代碼質量管控就會面臨以下問題:
1. 不同項目使用的代碼規范不一樣
2. 部分項目由于放松要求,沒有接入質量檢查,或者存在大量未修復的缺陷
3. 無法從團隊整體層面上體現各個項目的質量狀況對比
為了應對以上問題,需要建設中心化的代碼質量管控體系,要點包括:
代碼規范統一管理。通過腳手架命令垂直管理代碼掃描配置規則集, 自動安裝,不在本地寫規則。一個團隊、一類項目、一套規則。
* * *
* [待定] <u>使用統一的持續集成服務(Jekins/Travis等)。質量檢查不通過的項目不能上線。</u>
* [待定]<u> 建立代碼質量評分制度(借助Sonar)。讓項目與項目之間能夠橫向對比,項目自身能夠縱向對比,并且進行匯總反饋。</u>
Why
代碼質量是團隊技術水平和管理水平的直接體現。
看代碼的時間遠遠多于寫代碼的時間
目前前端項目出現的問題
-
書寫風格不統一, 閱讀體驗差
-
維護性差, 復用性差(Code Review互相進步)
-
容易出現低質量代碼, 代碼返工率高
-
git commit不規范
How
通過哪些手段來保證代碼質量
EditorConfig
[EditorConfig]( https://editorconfig.org/)在多人協作開發項目時候, 支持跨編輯器, IDE來支持維護一致的編碼樣式(文件格式)。
VSCode插件EditorConfig for VS Code提供一鍵生成.editorconfig。
查看[實例](https://editorconfig.org/#example-file)。
TypeScript
- [官網介紹](https://www.typescriptlang.org/
)。
- [中文awesome-typescript](https://github.com/semlinker/awesome-typescript)
- [TypeScript體系調研報告](https://juejin.im/post/59c46bc86fb9a00a4636f939)
- [2018年度JS趨勢報告](https://2018.stateofjs.com/javascript-flavors/overview/)
Git Hooks
Git能在特定的重要動作發生時觸發自定義腳本。有兩組這樣的鉤子:客戶端的和服務器端的??蛻舳算^子由諸如提交和合并這樣的操作所調用,而服務器端鉤子作用于諸如接收被推送的提交這樣的聯網操作, 我們目前使用的大多數是客戶端鉤子。
通過[husky](https://github.com/typicode/husky)集成[git hooks](https://git-scm.com/book/zh/v2/%E8%87%AA%E5%AE%9A%E4%B9%89-Git-Git-%E9%92%A9%E5%AD%90), 如果對git想有更全面的理解推薦閱讀[GIt文檔](https://git-scm.com/book/zh/v2)。
husky會安裝一系列的git hook到項目的.git/hook目錄中。
下面兩張圖分別對比沒有安裝husky與安裝了husky的git目錄區別:
當你用 git init 初始化一個新版本庫時,Git 默認會在這個目錄中放置一些示例腳本(.sample結尾的文件)。
pre-commit
pre-commit 鉤子在鍵入提交信息前運行。它用于檢查即將提交的快照,你可以利用該鉤子,來檢查代碼風格是否一致(運行類似 lint 的程序。
- [lint-staged](https://github.com/okonet/lint-staged): 可以獲取所有被提交的文件并執行配置好的任務命令,各種lint校驗工具可以配置好lint-staged任務中。
- [prettier](https://prettier.io/): 可以配置到lint-staged中, 實現自動格式化編碼風格。
- [stylelint](https://github.com/stylelint/stylelint)
- [eslint](https://cn.eslint.org/)
- [tslint](https://github.com/palantir/tslint)
- [eslint-plugin-vue](https://github.com/vuejs/eslint-plugin-vue): Vue.js官方推薦的lint工具
關于[為什么選擇prettier, 以及eslint 與prettier區別?](https://zhuanlan.zhihu.com/p/62542268)。
關于[prettier配置](https://prettier.io/docs/en/configuration.html)。
關于[stylelint配置](https://stylelint.io/user-guide/configuration/)。
關于[eslint配置](https://cn.eslint.org/docs/user-guide/configuring)。
commit-msg
[commitlint](https://github.com/conventional-changelog/commitlint)。
commit-msg 可以用來在提交通過前驗證項目狀態或提交信息, 使用該鉤子來核對提交信息是否遵循指定的模板。
關于git hooks在package.json配置:
測試
unittest
- - [Jest](https://jestjs.io/
- )
- - [Mocha](https://mochajs.org/
- )
e2e
- - [Nightwatch](http://nightwatchjs.org/
- )
- - [Cypress](https://www.cypress.io/
- )
CHANGELOG
更新日志, [standard-version](https://github.com/conventional-changelog/standard-version)。
Code Review
* [待定] Review制度,我們目前公司在代碼merge時候多人審核才通過。
如何快速落地到當前業務
前端腳手架(xx-cli)
采用中心化集中管理代碼掃描配置文件的思路, 把code lint配置文件做成一個npm包發到內網, 然后擴展腳手架命令一鍵執行下發遠程配置文件到本地項目, 并且把新增的package.json依賴打進來, 大家后面再安裝新的依賴即可。
所謂中心化管理: 所有項目代碼配置文件以遠程配置文件為準, 如果你本地有同名配置會被刪除, 這樣方便后續我們更新配置文件比如(增加vw/vh適配), 以及所有業務同步問題。
```
目前只有基于vue.js項目的lint腳本命令, 后續有別的項目, 考慮通過
xx-cli lint -- vue
xx-cli lint -- node
擴展
```
demo演示
demo演示如何在舊項目中植入代碼質量檢測?
由于這部分是在內網演示就不發不出來了。
至于腳手架可以參考我之前的demo[easy-cli](https://github.com/NuoHui/easy-cli)。這是比較全的demo。
Future
J ekins自動化
[Sonar](https://www.sonarqube.org/)
[Github:](https://github.com/SonarSource/sonarqube)
SonarQube 是一款領先的持續代碼質量監控平臺,開源在github 上,可以輕松配置在內網服務器,實時監控代碼,幫助了解提升提升團隊項目代碼質量。通過插件機制,SonarQube可以繼承不同的測試工具,代碼分析工具,以及持續集成工具。
與持續集成工具(例如 Hudson/Jenkins 等)不同,SonarQube 并不是簡單地把不同的代碼檢查工具結果(例如 FindBugs,PMD 等)直接顯示在 Web 頁面上,而是通過不同的插件對這些結果進行再加工處理,通過量化的方式度量代碼質量的變化,從而可以方便地對不同規模和種類的工程進行代碼質量管理。
行業內提到"代碼質量管理, 自動化質量管理", 一般指的都是通過Sonar來實現。
用Sonar能夠實現什么?
- 技術債務(sonar根據"規則"掃描出不符合規則的代碼)
- 覆蓋率(單元測試覆蓋率)
- 重復(重復的代碼, 有利于提醒封裝)
- 結構
- …
sonarjs
sonar支持多種編程語言, 其中包括JavaScript. 如[sonarjs](https://www.sonarsource.com/products/codeanalyzers/sonarjs.html).