前端項目 bug 太多?不存在的

程序員小皮 發佈 2020-02-11T18:26:06+00:00

軟體項目的前端部分由於太過零碎,細節很多,比後端更容易出現bug。Lint 規則可以在編輯器中自動運行,邊寫代碼邊提示,也可以集成到 CI 流程里。

Bug 會降低軟體產品的用戶滿意度,也會影響產品開發的進度。軟體項目的前端部分由於太過零碎,細節很多,比後端更容易出現 bug。那麼,如何儘可能地降低前端項目的 bug 呢?

本文總結了幾個建議,希望對你有所幫助。

Lint

Lint 的作用是找出不符合設定風格的代碼。Lint 規則可以在編輯器中自動運行,邊寫代碼邊提示,也可以集成到 CI 流程里。通過 Lint 我們能夠儘早發現一些低級錯誤,從而提高代碼質量。

很多程式語言都有 Lint 工具,JavaScript 也不例外。JavaScript Lint 工具有好幾種,目前最流行的是 ESLint。

ESLint 集成了大量適用於現代 JavaScript 代碼的規則。我們可以在.eslintrc 這個 JSON 文件里配置規則,包括啟用和禁用、設置級別等。也可以直接採用社區現成的一套規則,這樣就不用自己一個一個配置了。

考考你,你能用肉眼看出下面代碼的問題嗎?

通過 npm 可以非常方便地安裝 ESLint,很多編輯器也有各種插件可以高亮顯示有問題的代碼。以 VS Code 為例,裝上 ESLint 插件 後,可以清楚地看到代碼里的問題:

看到沒,還不止一個問題呢!

如果我們用 TypeScript 來寫代碼,可以用TSLint。它跟 ESLint 非常相似——包括規則配置、預設規則集合和 VS Code 插件。

代碼 Lint 在前端項目里很容易實現,並且會帶來顯著的收益,你值得擁有。

代碼自動格式化

Lint 工具發現的一些代碼風格問題能不能自動糾正?例如,自動添加缺失的分號?完全可以!這就是代碼格式化的用武之地。來看下面的代碼:

在 code review 的時候看到這種代碼估計會皺眉頭,這代碼能看出什麼問題?

Prettier 可以用來自動格式化代碼。VS Code 有Prettier 插件 ,可以在保存代碼時自動格式化。

來看格式化後的代碼,是不是好看多了:

代碼格式化很容易實現,配合 lint 工具使用,這樣我們就能更容易發現代碼里的 bug。

靜態類型檢查

靜態類型同樣可以讓我們在寫代碼的時候儘早發現問題。你能找到下面這個 JavaScript 函數的錯誤嗎?

這裡的 bug 在於我們引用的 response 對象結構,Lint 無法檢測出來。除非我們對該結構非常熟悉,否則也很難發現問題所在。如果我們定義了response對象的類型呢?編譯器會檢查我們是否引用了正確的對象類型。TypeScript 就是幹這個的。

現在我們給 response對象加上類型後,你應該看到問題在哪了吧?

截圖裡的編輯器是 VS Code,對 TypeScript 有很好的支持,一旦發現問題就會立即高亮顯示錯誤信息。

TypeScript 在 JavaScript 上面加了一層靜態類型檢查系統,目前非常流行。實際上vue 3.x 就是用 TS 寫的。

TypeScript 編譯器是高度可配置的,無論是新項目還是老項目,都可以引入 TypeScript,以便儘早發現 bug。

自動化測試

Lint、代碼格式化以及靜態類型檢查不需要太費勁就可以加入到項目中。而自動化測試就比較費勁了,但是它能發現更多複雜的 bug,因此也是值得的。

Jest 是一個很不錯的測試工具,可以用來測試 JavaScript 函數和前端組件。它在測試 React 和 Vue 應用方面非常受歡迎。它還能提供 mock 功能,當測試失敗時會給出有用的錯誤信息:

在編寫單元測試時,了解代碼覆蓋率是非常必要的。在 Jest 中,只要添加--coverage參數就能得到代碼覆蓋率報告:

利用這些信息,我們可以計劃後續的測試。

單元測試可以確保應用的各個部分按預期工作,並且可以讓我們可以放心地修改代碼,持續開發。但是,它不能給我們保證整個應用的關鍵業務流程隨著開發的持續推進仍然能夠繼續工作。這時候「端到端測試(E2E)」就派上用場了。Cypress是個很好的 JavaScript E2E 測試工具。Cypress 在調試失敗測試時非常出色,因為測試運行在瀏覽器上,我們能夠用上 Chrome DevTools 的所有功能。

除了能確保應用的關鍵部分能繼續工作,E2E 測試通常更容易集成到已有項目中去,因為它跟代碼是解耦的。但是,E2E 測試更加脆弱,因為它依賴於應用程式的所有層——對應用程式依賴的數據做一點小小的更改就可能導致大量測試失敗,卻沒有發現真正的 bug。

因此,它的成本會更高,但是如果很好地結合單元測試和 E2E 測試,可以在回歸過程中發現 lint 和類型檢查發現不了的 bug。

充分利用框架/庫

減少 bug 的另一個方式是少寫代碼,少重複造輪子,充分利用經過測試的第三方代碼。

使用 React,Vue或 Angular 這樣的框架可以大大減少自有代碼,更重要的是可以大大減少 bug。這三大框架都有繁榮的技術生態,有著大量健壯的第三方庫,比如狀態管理工具和 UI 組件。

但是要注意,引入大量的依賴庫也會讓項目不堪重負,有可能面臨嚴重的性能問題。如何避免性能問題呢?

關注性能

開發應用時,我們可以利用 Chrome 的 DevTools 密切關注性能。

首先我們可以利用 Network 面板查看 HTTP 請求。有大荷載請求嗎?是否過於頻繁地請求某個資源?大荷載請求和頻繁請求都會影響頁面性能。DevTools 還能模擬低速網絡環境,可有效地幫助定位這類性能問題。

實際上 DevTools 里的 Performance 面板有個專門分析性能的介面。我們可以錄製一段時間的使用情況,得到性能相關的時間線數據,可以幫助我們定位性能瓶頸所在。

有必要用它分析一下你的應用,看看性能有沒有下降。

解決性能問題的代價很高,因為通常需要重構代碼。因此,定期使用上述工具儘早發現這些問題是非常值得的。

儘可能使用純函數

請看下面的代碼:

該函數接受一個對象參數並返回同一個對象,並將字符串屬性值都轉成小寫。你能發現這段代碼的潛在問題嗎?

問題就在於該函數修改了傳給它的參數。代碼的其他地方可能依賴這個對象的初始狀態。這些都是細微的 bug,卻需要花費大量的時間來確定和修復。

如果用純函數來寫,是這樣的:

純函數對於相同的參數總是返回相同的值,並且不會產生任何副作用,比如改變參數。不改變參數意味著函數不會在代碼的其他位置引起 bug。

第二種寫法的函數利用了數組的 reduce函數來創建新對象,沒有改變原有對象。數組還有幾個函數也有這個特性:

  • concat
  • filter
  • map

檢查瀏覽器兼容性

一個常見的需求是要支持所有主流瀏覽器。如果我們用了一個之前從來沒有用過的特性,我們可以在caniuse.com上查看瀏覽器兼容性。

別寫了一段漂亮的代碼,最後卻發現在 IE 上跑不起來,那就悲催了!

線上錯誤監控

即使做了上述所有措施,還是有可能在生產環境發現 bug。如果能在用戶上報之前發現這些 bug,豈不更好?這就需要用到錯誤上報工具了。可以自己實現錯誤上報邏輯,也可以用第三方工具。

總結

減少前端項目 bug 的方法有很多,有的很簡單易行,比如代碼格式化和 Lint,有的代價稍微高點,比如自動化測試。

儘早發現和減少 bug 能提高用戶滿意度,我們也有更多時間開發更多功能!

關鍵字: