前端代碼質量管理(一)

導語: 隨着業務的增加和開發團隊的成員快速增長,其中不少新人來自於五湖四海各大門派,在編碼的風格和習慣中也出現各異。 一般在相互 codereview 時發現不少代碼上的問題,長此以往代碼出現了代碼難以維護的問題,甚至還會出現低級錯誤。 所以,我嘗試在前端代碼質量的管控上作了些探索,也總結了一些經驗分享給你們。
做者:鄭振波css

本文大綱介紹

  • 編碼規範
  • 冗餘文件與代碼

1. 編碼規範

在一些老項目裏咱們常會遇到如下問題:html

編碼規範
相信編碼規範對於你們來講不算是陌生,若是在 9102 年再次聊起這個話題,恐怕耳朵會起繭,但編碼規範從制定到落地是一個艱難的旅程,特別是對於不一樣成員的編碼習慣,還有棘手的祖傳代碼。不管你是老司機仍是新手不妨瞭解一下。

1.1 編碼規範的制定

如何制定編碼規範?這是一個永恆的話題,甚至出現過開發者按照本身的習慣和想法不停的去修改 eslint rules,沒錯,主觀性很是強的開發者就會這麼幹,最後發現 eslint rules 成了一鍋粥。前端

若是客觀些也許會在這三個方面去思考問題:

  • 兼顧習慣:儘量兼顧團隊各成員習慣,人是有個性的,要兼顧彷佛不大可能。
  • 規則從嚴:規則越嚴格越好,也毫不讓他鬆散無約束。
  • 投個票:投票彷佛是最民主的決定,但每每最具爭議的 rules 會出現票數差別不大。

若是你能從以上三個方法中取得成果,那說明你是老闆,這一切就會變得太簡單了。但不管如何,每個被擴展的 rule 都能找到具支持點和反駁點,在制定規範時同窗們一般每每會在幾個點去發表他的意見:node

  • 習慣:「我一直都這樣幹,沒問題」
  • 業界標準:「你去看某某大公司的開源代碼吧」
  • 必要性:「行尾不加分號我從沒見過跑不起來的JS」
  • 耗時:「按一次 tab 比按兩次 tab 省時省力;行尾加分號簡直浪費生命」

1.2 在編碼質量和編碼效率之間取得平衡

有沒有辦法能夠解決這些爭論?怎樣取得平衡?開源社區各團隊開源出的 eslint rules 能夠說是遍地開花,prettier,eslint-config-standard,airbnb 等等,在編碼規範選型時應該考慮如下幾點:webpack

  • 適合項目的技術選型:好比咱們的團隊技術棧使用了 React 、Node.js,ES6,那麼就能夠很清晰地知道怎麼選擇方向了。
  • 社區承認度高:相信社區爭論程度不亞於團隊成員,若是一個規範獲得 stars 超過 1w,已是很了不得的事情了。
  • 是否有插件支持:可以支持 ESLint,JSCS 等。

基於以上標準,咱們選擇了超過 8w + 由 airbnb 前端團隊維護的 eslint rules。 標準制定後, 如何讓團隊成員快速適應起來?git

  • 配置編輯器:若是使用 VSCode,能夠配置 "eslint.autoFixOnSave": true,這樣保存代碼時會自動根據 eslint rules 去 fix 代碼,同窗們就很舒服了。
  • 編輯器插件:若是使用 VSCode 能夠安裝 Eslint 插件,這樣能夠實時提示不規範的代碼。

  • 構建時提示: 若是使用 webpack ,可使用 eslint-loader,再配合 eslint-friendly-formatter 能夠給到開發者很好的提示。能夠參考該文章 webpack引入eslint詳解

這樣 eslint 規範就初步落地了。github

1.3 整改祖傳代碼

定製好規範並落地後,如何對於祖傳代碼怎麼辦?因而咱們又遇到不一樣的聲音:web

  • 這代碼不是我寫的:」誰寫誰來 fix 啊「
  • 我不敢改: 「改出問題要背鍋怎麼說」
  • 下次再改:「趕時間發佈呢,要不就下次再改」
  • eslint-disable:「disable 大法好,沒有東西能夠攔住我了」

如下是咱們對祖傳代碼的整改之路: 首先要看看問題有多嚴重:npm

npx eslint src
複製代碼

eslint errors
25W+ Eslint 報錯,這不知道要改到什麼猴年馬月了。

1.3.1 添加 .eslintignore 文件,排除第三方 js 文件

但通過排查發現,這裏面大部分報錯是來自於第三方庫,但又不是 npm 包,這些文件每每是不能知足當前的編碼規範的,而且有部分是通過代碼壓縮,更不該該走 eslint 檢查。屏蔽掉第三方文件的檢測後,剩下的 eslint errors 還有 2w+,錯誤歸類: json

eslint errors
能夠發現錯誤類型最多的是換行符。

1.3.2 關於CRLF

在文本處理中,各操做系統也是有本身的一套標準:

Dos 和 windows 採用「回車+換行,CR/LF」表示下一行; UNIX/Linux 採用「換行符,LF」表示下一行; 蘋果機(MAC OS 系統)則採用「回車符,CR」表示下一行。

因此,若是團隊中還有 windows 玩家那麼建立文件的換行符就是 CRLF,這也談不上是什麼很大的缺點,但在若是趕上了 Vim 或 Emacs 玩家打開文件就會看到這樣的狀況:

每行後面會帶上個 ^M。爲了維護代碼世界的和平,一般須要統一轉換爲 LF 換行符:

  • 設置 IDE 換行符,如 VSCode:

  • VSCode 默認配置:文件 - 首選項 - 設置 -搜索:默認行尾字符。修改成 \n
  • EditorConfig: 若是你的項目中有 EditorConfig 那就更好了:

#Unix-style newlines with a newline ending every file [*] end_of_line = lf insert_final_newline = true

  • 配置 git config:能夠在 git commit 時把代碼統一轉爲 LF,那麼能夠了解一下 git config core.autocrlf ,也許你會見過這個配置,但不必定正確使用,其實他有3個值可配置:

ture: git pull 時會把 LF 結尾轉爲 CRLF false: git pull 時不作任何轉換 input: git pull 時會把 CRLF 轉換爲 LF

那麼這裏應該使用的是 git conifg core.autocrlf input 以上任何一條均可以解決你的換行符問題。

1.3.3 自動修復

解決好這一切以後,能夠嘗試讓 ESLint 自動修復一波了: npx eslint src --fix

自動修復後還有 800+ ESLint 報錯,因而打開這些代碼 review 後,發現有不少問題,覺得規範人人都懂,正如那句電影臺詞**「聽過不少道理,卻依然過很差這一輩子」**。
這些都是很低級的錯誤,若是你尚未使用上 ESLint 那最好別太相信本身的代碼。

1.3.4 按期整頓

800+ 的錯誤分佈在各個頁面,能夠給團隊成員每人分配幾個頁面修復並分批上線,這樣大規模的修復最重要的是發佈後的監控:

發佈後監控

1.4 曾經覺得 ESLint 是萬能的

也許你會認爲 ESLint 沒有報錯那就 O**K了,其實坑每每沒那麼容易被發現,就像下面這個例子:

這裏提示 絕對路徑的引入應寫在 相對路徑引入的前面,因而快速改他一波:
這裏就有問題了,你看出來了嗎?應該怎麼改?

1.5 守住規則

咱們通過制定規範,代碼整改,接下來須要守住規則,不然一切徒勞

  • git hook:可使用 pre-commit,husky 等工具來配置 git 鉤子,配合上 npm script 能夠作到在提交代碼前執行 eslint 命令來檢測變動文件是否符合規範,不然 exit 非零值來終止 git commit。但在前端使用 git hook 缺點也是有的,好比每次提交代碼都要等待 eslint 一遍,致使開發體驗大大降低;也會出現有同窗自行刪除 pre-commit hook 文件來繞過檢測的狀況;也能夠經過添加 --no-verify 來關閉檢測。
  • web hook:好處是使用服務端來作校驗,沒法在前端繞過,缺點是須要使用服務器資源。關於如何搭建 web hook,能夠參考這篇文章

1.6 關於前端代碼規範的其餘思考

以上提到的是關於 JS 代碼規範的內容,對於 CSS 也可使用 stylelint 來作規範檢測,但這些更多的是對代碼的格式作規範,若是想把代碼寫好 ESLint 之類的並非全能的,好比代碼的整潔之道,這裏列舉了很多能夠參考的範式,恰又是 ESLint 沒法幫你 hold 住的點,因此 ESLint 並非萬能的。

2.冗餘文件與代碼

2.1 關於冗餘文件

也許你會認爲冗餘文件是一個問題,但他不是一個很關鍵的痛點,若是你的團隊追求極致,有很是的代碼潔癖,那麼冗餘文件也應該重視起來。即便你是一名老鳥,也有可能產生冗餘文件。

2.2 爲何會產生冗餘文件

在代碼的迭代過程當中,每每容易忽略刪除相應的文件,大概有兩種場景: 一、刪除 JS 代碼中的 require,卻忘記刪除相應的文件(img/css/js/etc.)。 二、刪除 CSS 中的 background ,忘記刪除相應的圖片文件。 刪除代碼很痛快,只要頁面刷新一波沒有報錯就以爲 o**k 了,日積月累的冗餘文件慢慢讓整個倉庫愈來愈大。

2.3 清理冗餘文件

若是使用 webpack 構建,那就能夠很方便地分析出整個項目的依賴關係。 第一步:在根目錄跑命令,把文件的依賴關係導到 stats.json 中,這個步驟耗時略長,我在項目中跑了一次,1420 個文件耗時 35s。

webpack --json > ./stats.json
複製代碼

第二步:使用 glob 獲取目錄下的全部文件路徑:

glob('!(node_modules)/**/*.*')
複製代碼

結合第一步生成的 stats.json 能夠過濾出未被引用的文件。

2.4 冗餘代碼

2.4.1 關於冗餘的 CSS

要分析項目中冗餘的CSS,實際上是比較困難的,主要緣由有 3 個方面: 一、頁面的元素或組件的嵌套:致使沒法只從靜態分析的層面上判斷樣式是否有做用於對應的元素上。 二、樣式的全局做域:a.css 中聲明一個樣式,他能夠做用於頁面上的任何一個 dom,這樣分析起來要遍歷項目中全部的 dom 和 css,一個樣式的聲明須要檢查全部的 dom,若是有N個樣式聲明那將會有很是大的計算量。 三、css 沒有約束: 多個 css 文件的樣式也能夠做用於一個 dom 元素上,由於每每會用到開源的 ui 庫,會根據設計的要求對相應的 dom 元素作樣式覆蓋,因此這種過於靈活的特性帶來的不可控形成難以管理。

2.4.2 解決冗餘的 CSS

CSS Modules 能夠把 css 做用域收斂,能夠顯式聲明哪一個 class 樣式做用於 dom 上,能夠保證某個組件的樣式不會影響到其餘組件:

樣式與 dom 造成了強依賴關係,這樣就能夠便於作靜態分析,能夠藉助 eslint-plugin-css-modules
若是 scss 裏面存在未使用到的 className,會獲得提示:
若是在代碼中使用了未定義的 className,也會有提示:

2.5.1 關於冗餘的 JS

在代碼迭代中,頗有可能刪除掉一些方法的使用,那麼會在 Class 留下一些多餘的方法,這些也是難以經過 eslint 來檢測到的,由於沒辦法判斷這些方法在實例化後,是否會在某個時刻被使用到。若是要找出這些冗餘的方法,也須要從整個項目開始分析全部 JS 的依賴關係,那麼計算量就會很是大,而且很耗時。

2.5.2 嘗試解決冗餘的 JS

目前沒有什麼好的辦法來解決這個問題,或許能夠經過兩種方式來分析出來: 一、命名約定: 好比如下劃線開頭的方法是私有方法,那麼就能夠只針對本文件全部的私有方法是否被使用來作分析了。 二、註釋標記:若是不喜歡下劃線的方式,那麼也能夠考慮添加註釋來標記。

2.6 冗餘文件/代碼 小結

一、刪除代碼要留心 二、分析冗餘 三、合理運用工具 四、發佈後監控

相關文章
相關標籤/搜索