如何保障前端項目的代碼質量

對於中大型前端項目,項目規範與代碼質量尤爲重要。當功能需求變更或需要重構時,隨心所欲的(糟糕的)代碼可能帶來比重新開發還麻煩的問題。

1 前端項目代碼中的常見問題

1.1 凌亂的書寫風格,閱讀體驗差

這個問題不用作過多闡述,想必接手過他人代碼的同學,多少都有些體會。簡單來說,太過隨意的代碼會讓強迫症患者難以容忍,難以閱讀理解的代碼有時甚至不如推倒重來。

1.2 低質量的編碼,bug 不斷

什麼樣的代碼是低質量或高質量的?好的代碼可能會讓你如讀小說一般被吸引,糟糕的代碼會讓你看一眼就不想繼續、甚至看半天而不知所云。

有人可能認爲初級程序員纔會有這種問題,其實不然,一些工作經驗兩三年的同學寫的代碼依然如此。對於一些個人自學意識不夠積極、沒有團隊規範性指引的同學,很容易習慣成“學習半年、然後重複三年無長進”的情況。

拿出來你可能不太願意相信,下面這些例子即來源於真實項目。你能儘可能地找出其中存在的各種問題嗎?

圖1

圖2

圖3

圖4

圖5

圖6

圖7

以上只是截取的一些很簡短的列子,那麼涉及大塊複雜邏輯的地方會是怎樣的,試試發揮一下你的想象力。

1.3 功能不分離,邏輯糅合,難以閱讀和理解

這種問題其實是非常普遍的。一個函數幾百行、一個文件數千行、一個類幾十個方法、方法參數定義隨意、沒有任何註釋、方法與變量命名無明確的語義、數據修改與變更穿插在各種方法中等等。 這樣的編碼方式,你要去理解它的邏輯往往真的很難,一般只能一塊塊一行行的去做閱讀理解(可能還會開啓邊看邊罵娘模式)。

這主要原因在於開發者個人的基礎知識能力、編碼經驗和意識等的不足。

其實針對這種情況,常見的開源的編碼規範都會有所提及。我的建議是這些同學應該好好溫習一下面向對象編程、函數式編程、數據結構、常見設計模式,看一看各種開源的編碼規範並嘗試去真正的理解它們。當你回顧一個月前的代碼時,發現可以改進或重構使得編碼邏輯更爲簡潔清晰,說明你是在成長與進步的。

經常看到各種社區中都會有同學問這類問題:新項目正在選型,Vue.js、React、Angular 三大框架哪個合適?其實團隊開發成員對這些都比較有經驗,哪種都可以;如果團隊成員前端開發經驗大都不是太豐富或人員不夠穩定,選擇 Vue.js 最適合,爲什麼?因爲它更簡單簡潔,容易上手。Vue.js 通過 prop、data、computed、method、watch 等各種鉤子,一定程度上限定了編碼方式與風格,使得初級開發者寫出來的代碼也不會太難看,這也是它越來越受社區推崇的原因之一。

2 保障前端項目編碼質量的方法

如何保障前端項目的編碼質量呢?依我看來可以從這幾個角度考慮:制定編碼規範、開發工作流 lint 風格強制檢查、定期 Code Review、單元測試。

2.1 制定項目編碼規範

團隊協作項目中,編碼規範尤爲重要。對於初級程序員,因經驗欠缺,編碼規範的要求可以避免許多低級問題的產生;對於多人團隊來說,風格一致的編碼約定,在協作開發、代碼移交等時,可以在很大程度上降低風險和成本。

那麼編碼規範應當如何制定?

沒有最好的風格,只有團隊認同的一致性約定。一般來說可以由團隊負責人牽頭制定,成員提意見補充,最後落地成團隊規範並嚴格執行。業界有很多優秀前端團隊開源的規範可供參考。如:

學習編碼規範約定是有必要的,但你能在看完後並真正的理解它們嗎?

2.2 在開發工作流中配置 lint 風格檢查與修正

在開發工作流中引入工具輔助,可以強制性地實現編碼書寫和提交過程中的 lint 校驗。可以怎麼做?條條大道通羅馬,下面以當前流行的 Git Hook 方案舉例供參考。

2.2.1 開發編輯器及 lint 工具配置

我們在項目中配置 TSLint 插件以校驗 typeScript;配置 styleLint 插件以校驗 CSS/LESS。

我們約定團隊開發均採用 vscode 編輯器,並至少安裝以下插件輔助開發:

  • TSLint
  • stylelint
  • Document This
  • EditorConfig for VS Code
  • Prettier - Code formatter
  • Debugger for Chrome

2.2.2 添加 .editorconfig 文件

由於不同開發者可能使用的編輯器不同,但各種編輯器基本都支持 .editorconfig, 故每個項目都應當包含 .editorconfig,用來統一配置編輯器的換行、縮進存儲格式。

配置參考:

# http://editorconfig.org
root = true

[*]
indent_style = space                    # 輸入的 tab 都用空格代替
indent_size = 2                         # 一個 tab 用 2 個空格代替
# end_of_line = lf                      # 換行符使用 unix 的換行符 \n
charset = utf-8                         # 字符編碼 utf-8
trim_trailing_whitespace = true         # 去掉每行末尾的空格
insert_final_newline = true             # 每個文件末尾都加一個空行

[*.md]
trim_trailing_whitespace = false        # .md 文件不去掉每行末尾的空格
複製代碼

2.2.3 配置 Git Hook 強制執行編碼風格檢測與修正

藉助 Git Hook,可以在提交代碼時執行風格檢測與修正,當存在無法通過的內容時,提交會被 block,從而實現編碼規範的強制性執行。

可以利用以下幾個工具來實現這個流程:

  • husky 它會安裝一系列 git hook 到項目的 .git/hook 目錄中,這些鉤子可以檢測 package.json 中的 scripts 腳本命令配置,並在代碼提交時執行它(我們這裏利用 pre-commit 鉤子)
  • lint-staged 可以取得所有被提交的文件並依次執行配置好的任務命令
  • styleLint/TSLint/ESlint 各種 lint 校驗工具,可以配置到 lint-staged 的任務中
  • prettier 配置到 lint-staged 的任務中,可以實現修正可自動格式化的編碼風格

package.json 中的相關配置信息參考:

{
  "scripts": {
    "precommit": "lint-staged",
  },
  "lint-staged": {
    "*.ts": [
      "tslint --fix",
      "prettier --parser typescript --single-quote --print-width 120 --write",
      "git add"
    ],
    "*.less": [
      "stylelint --fix",
      "prettier --parser less --print-width 120 --write",
      "git add"
    ]
  },
  "devDependencies": {
    "husky": "^0.14.3",
    "prettier": "^1.13.5",
    "prettier-stylelint": "^0.4.2",
    "stylelint-config-standard": "^18.2.0",
    "stylelint": "^9.4.0",
    "stylelint-config-prettier": "^4.0.0"
  }
}
複製代碼

.prettierrc 配置文件參考:

{
  "singleQuote": true,
  "trailingComma": "es5",
  "printWidth": 120,
  "overrides": [
    {
      "files": ".prettierrc",
      "options": { "parser": "json" }
    }
  ]
}
複製代碼

.stylelintrc 配置配置參考:

{
  "extends": [
    "stylelint-config-prettier",
    "stylelint-config-standard",
    "./node_modules/prettier-stylelint/config.js"
  ],
  "rules": {
    // 定義一些適合團隊約定的規則
  }
}
複製代碼

通過以上配置,當代碼提交時,會在 pre-commit 階段執行 .git/hook/precommit 鉤子,該鉤子會查找並執行 scrpits 中的 precommit 命令,於是 lint-staged 定義的任務會被逐個執行。這套方案也是當前比較流行的做法,在很多開源項目中都有所應用。

拓展閱讀:

2.3 執行 Code Review

編碼規範與 lint 檢查只能讓大家的編碼風格保持一致性,卻無法避免低質量輸出的問題。而這種問題對團隊和產品來說往往卻是致命的。

低質量的代碼不僅僅只是會製造各種低級 bug,讓測試同學測到沒脾氣,對產品來說,可能很小的需求改動卻需要代碼有巨大的變動,導致產品迭代週期被潛在地延長。另外,當大家的精力總是聚焦於需求開發和 bug 修復時,產品設計的細節就顧不了那麼多了(別跟我說什麼精益求精,趕時間解決完 bug 就燒香拜佛了),這對產品體驗來說也是很要命的。

什麼樣的代碼是好的,什麼樣的代碼是不好的?這來源於知識的學習運用和開發經驗的日積月累。低質量的編碼說到底還是經驗不同、水平存在差異。對於個人來說要通過不斷的學習積累自我提升,對於團隊來說進行 Code Review 評審是有必要的。

那麼 Code Review 應當如何進行?

Code Review 的形式可以多種多樣。如 GitHub 上許多流行項目採用 PR(Pull Request) 工作流的方式,一個 PR 至少經過三人次 review 通過才能合入,這能從流程上較好地保障項目代碼質量。在有的開發團隊或企業,會引入 gerrit 這種代碼審覈平臺,過程與此大致相似。但對許多快速迭代的業務產品開發團隊來說,這種需要多人評審通過的模式都不太適合:人力有限、時間緊迫、顧不了那麼多了,於是即使 gerrit 也流於形式,編碼質量只能落到開發人員個人的肩膀上。

相比較而言,定期進行小組討論形式,問題的提出可以得到快速反饋和總結,這會讓大家更有動力一些。

一般來說團隊內有新人入職,基本的 Code Review 是有必要的,這時候編碼規範與風格是 review 的重點。當大家對常見的基本問題都有了比較一致且明確的認識後,探討交流學習則會逐漸成爲 Code Review 的主要內容。

對於內部交流氛圍濃厚的團隊,可以鼓勵成員之間互相審閱提交的編碼。對大多數團隊來說,可以這麼來做:主要負責人以抽查瀏覽的形式快速審閱成員提交的代碼,發現有問題的地方提出並打回改進(問題較多的同學的代碼應重點關注);團隊定期(可以是每週)以例會討論的形式,對一週提交的代碼進行抽樣和總結式評審,學習好的編碼方式、探討不好的編碼的理由,甚至進而沉澱出適合團隊的編碼約定。

另外注意一點,Review 過程的操作方式和表達用語非常重要,應當是輕鬆的溝通交流學習的方式,不要把 Code Review 執行成了批判會。

拓展閱讀:

2.4 編寫單元測試

前端項目寫單元測試,對很多人來說是不願意的,因爲編寫過程太過複雜。但基本的單元測試是可以寫的,公共方法和組件的修改可能會爲某些調用模塊製造潛在的 BUG,良好的單元測試可以在出現問題時快速反饋出來。

我們當前對項目單元測試的基本要求是這樣的:

  • 公共方法、服務類必須寫單元測試
  • 公共組件應當書寫單元測試,應儘可能覆蓋到各種功能點
  • 業務組件可以書寫簡單的測試
  • 注意測試代碼質量,應當反覆通過測試覆蓋率評估和改進測試代碼

Vue.js/React/Angular 三大框架都有完善的單元測試實現體系,在項目中引入單元測試的成本並不高,高的是測試代碼編寫的過程。在某些情況下我認爲這種“高成本”是值得的。另外需注意,單元測試的執行一定要與 CI 集成,才能真正發揮它實時性反饋問題的作用。

2.5 其他

2.5.1 使用靜態檢查語言 TypeScript / Flow

JavaScript 是一種語法簡單使用靈活的弱數據類型語言,而正是這種過於靈活的特性,使得開發者能夠任性地書寫,但任性是需要成本和代價的。

有時會看到一些後端同學會說,前端看上去也沒那麼難嘛,我只學了一天就開始上手擼代碼了。他們或許說的沒錯,但是有經驗的前端同學去看一下他們此時產出的代碼,往往都會表示不忍直視。許多前端開發的同學並非計算機相關專業出身,沒有太多相關的基礎理論知識作爲背景,剛開始幹活時在代碼輸出上“隨心所欲任意妄爲”的情況更爲普遍。

TypeScript 和 Flow 近兩年來越來越火熱,幾乎當前流行的前端開源產品都在轉向使用它們,這足以體現它們存在的重要價值。靜態檢查語言在編碼階段即可檢測並提示出潛在的類型引用風險,可以在很大程度上避免許多因粗心、誤用帶來的邏輯 bug。良好的類型定義會使得項目模塊邏輯結構更爲清晰可控。藉助編輯器強大的類型提示功能,代碼編寫甚至無需看詳細文檔即可快速瞭解用法。特別是中大型的複雜項目,選用它們絕對是利大於弊。

2.5.2 構建頁面埋點統計平臺

對於產品質量而言,監控體系是非常重要的一部分。對於前端而言,可以通過設計網站埋點統計平臺來收集頁面信息,如腳本報錯、頁面性能卡頓等問題,基於統計信息回溯分析問題根源,進而進行問題修復和代碼改進。當然統計數據的作用絕不止這些,這裏不作過多的擴展講述。

拓展閱讀:

3 相關參考

關於前端編碼質量,你有哪些經驗體會呢?歡迎來一起探討交流。


作者:任俠
鏈接:https://juejin.im/post/5b911f306fb9a05cdb1013b9
來源:掘金
著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章