非常全面的前端協作規範(長文建議先收藏)
- 2019 年 10 月 6 日
- 筆記
原文作者:掘金 _sx_
原文鏈接:https://juejin.im/post/5d3a7134f265da1b5d57f1ed
萬字長文,繼續刷新我的文章長度記錄,涉及前端開發的方方面面。本文將持續更新和完善, 文章部分觀點可能比較武斷或不完整,歡迎評論和補充,一起完善該文章. 謝謝
筆者長期單槍匹馬在前端領域廝殺(言外之意就是團隊就一個人),自己就是規範。隨着公司業務的擴展,擴充了一些人員,這時候就要開始考慮協作和編碼規範問題了。本文記錄了筆者在制定前端協作規範
時的一些思考,希望能給你們也帶來一些幫助.
一個人走的更快,一群人可以走得更遠,前提是統一的策略,還要不斷地反省和優化。
以下是目錄概覽, 看出這是一篇浩浩蕩蕩的長文
- 1 工作流規範
- 1.1.1 版本規範
- 1.1.2 版本控制系統規範
- 1.1.3 提交信息規範
- 1.1 開發
- 1.2 構建規範
- 1.3 發佈工作流規範
- 1.4 持續集成
- 1.5 任務管理
- 2 技術棧規範
- 2.1 技術選型
- 2.2 迎接新技術
- 3 瀏覽器兼容規範
- 3.1 確定兼容策略
- 3.2 確定瀏覽器分級
- 3.3 獲取統計數據
- 4 項目組織規範
- 4.1 通用的項目組織規範
- 4.2 目錄組織的風格
- 4.3 腳手架和項目模板
- 5 編碼規範
- 5.1 Javascript
- 5.2 HTML
- 5.3 CSS
- 5.4 代碼格式化
- 5.5 集大成的
- 5.6 特定框架風格指南
- 5.7 Code Review
- 6 文檔規範
- 6.1 建立文檔中心
- 6.2 文檔格式
- 6.3 定義文檔的模板
- 6.4 討論即文檔
- 6.5 注釋即文檔
- 6.6 代碼即文檔
- 7 UI設計規範
- 8 測試規範
- 8.1 測試的流程
- 8.2 單元測試
- 9 異常處理、監控和調試規範
- 9.1 異常處理
- 9.2 日誌
- 9.3 異常監控
- 10 前後端協作規範
- 10.1 協作流程規範
- 10.2 接口規範
- 10.3 接口文檔規範
- 10.4 接口測試與模擬
- 11 培訓/知識管理/技術沉澱
- 11.1 新人培訓
- 11.2 營造技術氛圍
- 12 反饋
CHANGELOG
- 2019.7.28 新增技術選型
- 2019.7.29 新增瀏覽器統計數據獲取
- 2019.9.6 建立技術氛圍一節 新增面試題庫
什麼是規範?
規範,名詞意義上:即明文規定或約定俗成的標準,如:道德規範、技術規範等。動詞意義上:是指按照既定標準、規範的要求進行操作,使某一行為或活動達到或超越規定的標準,如:規範管理、規範操作.
為什麼需要規範?
- 降低新成員融入團隊的成本, 同時也一定程度避免挖坑
- 提高開發效率、團隊協作效率, 降低溝通成本
- 實現高度統一的代碼風格,方便review, 另外一方面可以提高項目的可維護性
- 規範是實現自動化的基礎
- 規範是一個團隊知識沉澱的直接輸出
規範包含哪些內容?
如文章標題,前端協作規範並不單單指『編碼規範』,這個規範涉及到前端開發活動的方方面面,例如代碼庫的管理、前後端協作、代碼規範、兼容性規範;
不僅僅是前端團隊內部需要協作,一個完整的軟件生命周期內,我們需要和產品/設計、後端(或者原生客戶端團隊)、測試進行協作, 我們需要覆蓋這些內容.
下面就開始介紹,如果我是前端團隊的Leader,我會怎麼制定前端規範,這個規範需要包含哪些內容?
1 工作流規範
1.1 開發
1.1.1 版本規範
項目的版本號應該根據某些規則進行迭代, 這裡推薦使用語義化版本規範, 通過這個規範,用戶可以了解版本變更的影響範圍。規則如下:
- 主版本號:當你做了不兼容的 API 修改,
- 次版本號:當你做了向下兼容的功能性新增,
- 修訂號:當你做了向下兼容的問題修正。
1.1.2 版本控制系統規範
大部分團隊都使用git作為版本庫,管理好代碼也是一種學問。尤其是涉及多人並發協作、需要管理多個軟件版本的情況下,定義良好的版本庫管理規範,可以讓大型項目更有組織性,也可以提高成員協作效率.
比較流行的git分支模型/工作流是git-flow, 但是大部分團隊會根據自己的情況制定自己的git工作流規範, 例如我們團隊的分支規範
Git 有很多工作流方法論,這些工作流的選擇可能依賴於項目的規模、項目的類型以及團隊成員的結構.
比如一個簡單的個人項目可能不需要複雜的分支劃分,我們的變更都是直接提交到 master 分支;
再比如開源項目,除了核心團隊成員,其他貢獻者是沒有提交的權限的,而且我們也需要一定的手段來驗證和討論貢獻的代碼是否合理。所以對於開源項目 fork 工作流更為適合.
了解常見的工作流有利於組織或創建適合自己團隊的工作流, 提交團隊協作的效率:

- 簡單的集中式
- 基於功能分支的工作流
- Git Flow ?
- Fork/Pull Request 工作流
1.1.3 提交信息規範

組織好的提交信息, 可以提高項目的整體質量. 至少具有下面這些優點:
- 格式統一的提交信息有助於自動化生成CHANGELOG
- 版本庫不只是存放代碼的倉庫, 它記錄項目的開發日誌, 它應該要清晰表達這次提交的做了什麼. 這些記錄應該可以幫助後來者快速地學習和回顧代碼, 也應該方便其他協作者review你的代碼
- 規範化提交信息可以促進提交者提交有意義的、粒度合適的'提交'. 提交者要想好要怎麼描述這個提交,這樣被動促進了他們去把控提交的粒度
社區上比較流行的提交信息規範是Angular的提交信息規範, 除此之外,這些也很不錯:
- Atom
- Ember
- Eslint
- JQuery
另外這些工具可以幫助你檢驗提交信息, 以及生成CHANGELOG:
- conventional-changelog – 從項目的提交信息中生成CHANGELOG和發佈信息
- commitlint – 檢驗提交信息
- commitizen – ?簡單的提交規範和提交幫助工具,推薦
- standard-changelog – angular風格的提交命令行工具
1.2 構建規範
對於團隊、或者需要維護多個項目場景,統一的構建工具鏈很重要, 這套工具應該強調"約定大於配置",讓開發者更專註於業務的開發。筆者在<為什麼要用vue-cli3?>文章中提出了vue-cli3
更新有很多亮點,非常適合作為團隊構建工具鏈的基礎:
- 首先這類工具是推崇'約定大於配置'。即按照他們的規範,可以實現開箱即用,快速開發業務. 在團隊協作中這點很重要,我們不推薦團隊成員去關心又臭又長的webpack構建配置
vue-cli3
抽離了cli service層
,可以獨立更新工具鏈。也就是說項目的構建腳本和配置在一個獨立的service項目中維護,而不是像以前一樣在每個項目目錄下都有webpack配置和依賴. 這樣做的好處是獨立地、簡單地升級整個構建鏈- 靈活的插件機制。對於團隊的定製化構建應該封裝到插件中,這樣也可以實現獨立的更新。
我們可以選擇第三方CLI, 當然也定製自己的構建鏈,按照上面說的這個構建鏈應該有以下特點:
- 強約定,體現團隊的規範。首先它應該避免團隊成員去關心或更改構建的配置細節,暴露最小化的配置接口。 另外構建工具不僅僅是構建,通常它還會集成代碼檢查、測試等功能。
- 方便升級。尤其是團隊需要維護多個項目場景, 這一點很有意義
下面是社區上比較流行的構建工具. 當然,你也可以根據自己的團隊情況開發自己的CLI, 但是下面的工具依然很有參考價值:
- create-react-app – ?零配置開始React開發
- vue-cli – ?零配置、漸進增強的項目構建CLI
- parcel – 零配置的Web應用打包工具
- Fusebox – 高速易用的打包工具
- microbundle – 零配置, 基於Rollup,適合用於打包『庫』
1.3 發佈工作流規範
發佈工作流指的是將『軟件成品』對外發佈(如測試或生產)的一套流程, 將這套流程規範化後,可以實現自動化.
舉個例子, 一個典型的發佈工作流如下:

- 代碼變更
- 提交代碼變更到遠程版本庫
- 程序通過CI測試(例如Travis變綠)
- 提升package.json中的版本
- 生成CHANGELOG
- 提交package.json和CHANGELOG.md文件
- 打上Tag
- 推送
如果你遵循上面的規範,那麼就可以利用社區上現有的工具來自動化這個流程. 這些工具有:
- conventional-changelog-cli
- conventional-github-releaser
- 實際上自己開發一個也不是特別難的事情.
1.4 持續集成
將整套開發工作流確定下來之後, 就可以使用持續集成服務
來自動化執行整個流程。比如一個典型的CI流程:

持續集成是什麼,有什麼意義呢?
我們需要持續集成
拆成兩個詞分別來理解, 什麼是持續
? 什麼是集成
?
持續(Continuous), 可以理解為'頻繁'或者『連續性』. 不管是持續集成還是敏捷開發思維、看板,都認為『持續』是它們的基礎。
舉一個通俗的例子,比如代碼檢查,『持續的』的代碼檢查就是代碼一變動(如保存,或者IDE實時檢查、或者提交到版本庫時)就馬上檢查代碼,而『非持續』的代碼檢查就是在完成所有編碼後,再進行檢查。對比兩者可以發現,持續性的代碼檢查可以儘早地發現錯誤,而且錯誤也比較容易理解和處理,反之非持續性的代碼檢查,可能會發現一堆的錯誤,失之毫釐謬以千里,錯誤相互牽連,最終會變得難以收拾。
『持續』的概念,可以用於軟件開發的方方面面,本質上就是把傳統瀑布式的軟件開發流程打碎,形成一個個更小的開發閉環,持續地輸出產品,同時產品也持續地給上游反饋和糾正。

那什麼是『集成』呢?狹義的集成可以簡單認為是『集成測試』吧. 集成測試可以對代碼靜態測試、單元測試、通過單元測試後可以進行集成測試,在應用組成一個整體後在模擬環境中跑E2E測試等等。也就是說,在這裡進行一系列的自動化測試來驗證軟件系統。
廣義的持續集成服務,不僅僅是測試,它還衍生出很多概念,例如持續交付、持續部署,如下圖

OK, 總結一下為什麼持續集成的好處:
- 儘早發現錯誤,快速試錯。越早發現錯誤,處理錯誤的成本越低
- 自動化工作流,減少人工干預。人類比機器容易犯錯, 而且機器擅長做重複的事情
對於持續集成規範一般會定義這些內容:
- 執行的環境. 比如容器、Node版本、操作系統等等
- 觸發的條件。比如定時觸發、在哪個分支觸發、會觸發什麼任務等等
- 執行的任務
- 劃分持續集成的階段. 比如
- 檢查:包括單元測試和代碼lint. 所有push到版本庫的代碼都會跑這個階段. 一般可以在提交title中包含[ci skip]來跳過這個階段
- 構建: 對前端項目進行構建. 只有打上版本tag的提交或release分支會跑構建任務
- 發佈: 將前端的構建結果進行交付/發佈. 只有打上版本tag的提交或者release分支在構建成功後會跑發佈任務
- 定義持續集成腳本模板
常用的CI服務:
- Github
- Travis CI
- CircleCI
- 完整列表
- GitLab: Gitlab-CI
- 通用
- Jenkins
擴展
- 持續集成是什麼
1.5 任務管理

作為前端Leader少不了任務管理。看板是目前最為流行的任務管理工具,它可以幫助我們了解項目的進度、資源的分配情況、還原開發現場.
筆者畢業第一年在一家很小的外包公司中工作,初生牛犢不怕虎,我竟然給老闆推銷起了看板和敏捷項目管理,想要改善項目管理這塊效率低下問題,老闆表示很支持,但是其他成員積極性並不高, 結果當然是失敗的。
當時還起草了一份『看板實施細則』, 所以任務管理這一塊也算小有心得吧.
說說一些比較好用的工具吧:
- 基於issue看板 – 可以基於Gitlab或Github的Issue來做任務管理,它們都支持看板。很Geek,推薦
- Tower – 專門做看板任務管理的。小團隊基本夠用。我們現在就使用這款產品
- teambition – 和Tower差不多,沒有深入使用過
- Trello – 顏值高.
2 技術棧規範
筆者現在所在的公司之前前端技術棧就非常混亂,Vue、React和AngularJS三大框架都有, 而且風格相差也很大. 當時我就想收包裹走人. 關於技術棧不規範的下場可以參考印度的飛機: <為什麼印度的飛機頻繁被摔?>
很少有人能精通這三個框架的,更別說是一個團隊。
三大框架跟編程語言一樣都有自己的設計哲學,這跟庫是不一樣, 一個庫的替換成本很低;而框架的背後是一個架構、一個生態。每個框架背後牽涉着開發思維、生態系統、配套工具、最佳實踐、性能調優。要精通和熟練一個框架需要付出的成本是很高。
所以說團隊的開發效率是基於穩定且熟練的技術棧的。穩定的技術棧規範有利於團隊協作和溝通; 另外如果團隊精通這個技術棧,當出現問題或者需要深入調優, 會相對輕鬆。
前端技術棧規範主要包含下面這些類型:
- 編程語言 – Typescript或Javascript
- UI框架及其配套生態, 以及備選方案。其背後的生態非常龐大:
- UI框架
- 路由
- 狀態管理
- 組件庫
- 國際化
- 動畫
- 服務端渲染
- 腳手架、CLI工具
- 組件測試
- 樣式. 包含了命名規範、預處理器、方法論等等
- 動畫引擎
- QA. 包含了測試、Lint、格式化工具、監控
- 項目構建工具流. 例如webpack、vue-cli
- 包管理器。npm、yarn
- 項目管理工具
- 時間處理。例如Moment.js
- 模板引擎
- 開發工具
- 後端開發框架
- 工具庫
- 開發/調試工具
- 等等
可以參考一下我們團隊的技術棧規範
2.1 技術選型
如何從零對團隊的技術棧進行規範, 或者說怎麼進行選型呢?舉個例子, 先確定備選項, 你現在要選Vue還是選React(一個可能引起論戰的主題)?
恰好前幾天在SegmentFault回答了一個問題: <什麼時候用vue什麼時候用react?>, 我講了一個我們幾年前是如何決定要使用React還是Vue的例子(注意結果不重要!):

<談談技術選型的注意事項>這篇文章寫得非常好,給了我一些啟發。結合上面的回答的例子, 來講一講在對相關技術進行選型的一些方法(評分項):
- 選擇你最熟悉的技術。上面說到團隊如果熟悉該技術,則可以很好地控制使用過程中的風險,方便對程序進行調優。所以成員熟悉、或至少Leader熟悉程度,是技術選型的一個打分項。 我們團隊最終選擇React的一個原因,就是我們熟悉它,它已經在現有的幾個應用中良好的運行了,所以 React + 1
- 選擇擁有強大生態和社區支撐的開源技術。有強大的生態和社區意味着,很多東西你不需要重複去造輪子,或者遇到問題可以很快解決,有更多的選擇。從公司層面、使用活躍的技術也比較好招人。 上面的例子也提到了這點,幾年前React的生態是強於Vue的,所以 React + 1
- 選擇成長期的技術。<談談技術選型的注意事項>裏面有一句話:'選擇一個技術的最低標準是,技術的生命周期必須顯著長於項目的生命周期' 我們選擇的技術應該是向前發展的、面向未來的, 這是選型的基本原則。所以我們一般不會去選擇那些'過氣'的技術,比如
AngularJS
(1.x)、Backbone
. 因為現在有更好的選擇,不必過於保守。 『向前』還意味着Leader要能夠預判該技術未來走向,這裡有很多參考因素,比如大廠的支撐、目前社區的活躍度、開發活躍度等等 React、Vue都非常有動力,比如React最近的React Hook、還有未來的ConcurrentMode、Async Rendering… 在這點上Vue和React打成平手吧 - API的穩定性。比較典型的例子就是Angular和Python,API不穩定會導致社區的割裂,也會導致項目升級成本變高、或者無法升級, 最終成為技術債。 不過值得慶幸的是因為有這麼多歷史教訓,現在開源項目在API變更上面是非常謹慎的,參考[譯] Vue 最黑暗的一天事件. 這點上React和Vue依舊打平
- 基礎設施配合。一個技術往往不是孤立存在的,它需要和其他技術相互配合,這種技術之間的融合度也是需要考慮的。 這個根據團隊使用情況來定,比如我們團隊統一使用Typescript,Vue跟Typescript配合使用其實不理想,所以 React + 1
- 業務考慮 <談談技術選型的注意事項> 提到一點就是『學會從業務端開始思考』. 意思就是選型需要充分地理解業務,理解用戶需求,當下需要解決的首要問題,以及可能的風險有哪些,再將目標進行分解,進行具體的技術選型、模型設計、架構設計. 一個典型的例子就是10年前火遍世界的
Rails
, 後端是使用Rails還是Java/C#/PHP這些傳統後端技術? 很多初創公司(如Github、Gitlab、Twitter)選擇了前者,他們需要快速開發原型、快速佔領市場, Rails開發很爽很快啊, 這種選型就是符合『業務需求的』。 那麼前端好像跟業務離得有點遠? 隨着『大前端』的發展,我們的工作對公司業務的影響只會越來越大。 比如上面提到的React Native,我們當時有考慮在移動端應用React Native技術,實現客戶端的跨平台,這就是業務影響啊。這時候React是不是又要 +1? 同理還有什麼服務端渲染、Serverless等等,期待前端的地位會越來越高
綜上,在這個案例中,React是勝出的。
擴展:
- 談談技術選型
- 談談技術選型的注意事項
2.2 迎接新技術
當然,對於團隊而言也要鼓勵學習新的技術、淘汰舊的技術棧。因為一般而言新的技術或解決方案,是為了更高的生產力而誕生的。當團隊容納一個新的技術選型需要考慮以下幾點:
- 學習成本。考慮團隊成員的接納能力。如果成本小於收穫的利益,在團隊裏面推行估計阻力會比較大
- 收益。是否能夠解決當前的某些痛點
- 考慮風險。一般我們不能將一個實驗階段的技術使用的生產環境中
就我們團隊而言,每個成員都有自己感興趣的方向和領域,所以我們可以分工合作,探索各自的領域,再將成果分享出來,如果靠譜的話則可以在實驗項目中先試驗一下,最後才推廣到其他項目.
3 瀏覽器兼容規範
前端團隊應該根據針對應用所面對的用戶情況、應用類型、開發成本、瀏覽器市場統計數據等因素,來制定自己的瀏覽器兼容規範,並寫入應用使用手冊中.
有了瀏覽器兼容規範,前端開發和兼容性測試就有理有據,避免爭議; 同時它也是前端團隊的一種對外聲明,除非特殊要求,不符合瀏覽器兼容規範的瀏覽器,前端開發人員可以選擇忽略。
3.1 確定兼容策略

漸進增強還是優雅降級. 這是兩個不同方向策略,漸進增強保證低版本瀏覽器的體驗,對於支持新特性的新瀏覽器提供稍好的體驗;優雅降級則是相反的,為現代瀏覽器提供最好的體驗,而舊瀏覽器則退而求之次,保證大概的功能.
選擇不同的策略對前端開發的影響是比較大的,但是開發者沒有選擇權。確定哪種兼容策略,應該取決於用戶比重,如果大部分用戶使用的是現代瀏覽器,就應該使用優雅降級,反之選擇漸進增強.
3.2 確定瀏覽器分級

YUI就曾提出瀏覽器分級原則,到今天這個原則依然適用。簡單說就是將瀏覽器劃分為多個等級,不同等級表示不同的支持程度. 比如我們團隊就將瀏覽器劃分為以下三個等級:
- 完全兼容: 保證百分百功能正常
- 部分兼容: 只能保證功能、樣式與需求大致一致。對於一些不影響主體需求和功能的bug,會做降低優先級處理或者不處理。
- 不兼容: 不考慮兼容性
一般而言, 根據瀏覽器市場分佈情況、用戶佔比、開發成本等因素劃分等級.
舉個例子,下面是我們對管理系統的兼容規範:

3.3 獲取統計數據

百度統計是中文網站使用最為廣泛的、免費的流量分析平台. 如上圖,通過這些統計平台可以獲取到終端真實的瀏覽器使用情況, 點擊查看示例。
如果公司沒有開發自己監控服務,還是建議使用這些免費的,有大廠支持的監控工具:
- 百度統計
- 友盟
- Google Analytics 需要kx上網
可以從這些地方獲取通用的瀏覽器統計數據:
- 百度流量研究院:主要提供國內瀏覽器統計
- statcounter: 國際瀏覽器統計
- 瀏覽器發佈年份統計
確定瀏覽器是否支持某個特性:
- caniuse
- MDN
4 項目組織規範
項目組織規範定義了如何組織一個前端項目, 例如項目的命名、項目的文件結構、版本號規範等等。尤其對於開源項目,規範化的項目組織就更重要了。
4.1 通用的項目組織規範
一個典型的項目組織規範如下:
- README.md: 項目說明, 這個是最重要。你必須在這裡提供關於項目的關鍵信息或者相關信息的入口. 一般包含下列信息:
- 簡要描述、項目主要特性
- 運行環境/依賴、安裝和構建、測試指南
- 簡單示例代碼
- 文檔或文檔入口, 其他版本或相關資源入口
- 聯繫方式、討論群
- 許可、貢獻/開發指南
- CHANGELOG.md: 放置每個版本的變動內容, 通常要描述每個版本變更的內容。方便使用者確定應該使用哪個版本. 關於CHANGELOG的規範可以參考keep a changelog
- package.json: 前端項目必須. 描述當前的版本、可用的命令、包名、依賴、環境約束、項目配置等信息.
- .gitignore: 忽略不必要的文件,避免將自動生成的文件提交到版本庫
- .gitattributes: git配置,有一些跨平台差異的行為可能需要在這裡配置一下,如換行規則
- docs/: 項目的細化文檔, 可選.
- examples/: 項目的示例代碼,可選.
- build: 項目工具類腳本放置在這裡,非必須。如果使用統一構建工具,則沒有這個目錄
- dist/: 項目構建結果輸出目錄
- src/: 源代碼目錄
- tests/: 單元測試目錄. 按照Jest規範,
__tests__
目錄通常和被測試的模塊在同一個父目錄下, 例如: /src __tests__/ index.ts a.ts index.ts a.ts 複製代碼 - tests: 全局的測試目錄,通常放應用的集成測試或E2E測試等用例
- .env*: 項目中我們通常會使用
環境變量
來影響應用在不同運行環境下的行為. 可以通過dotEnv來從文件中讀取環境變量. 通常有三個文件: 基本上這些文件的變動的頻率很少,團隊成員應該不要隨意變動,以免影響其他成員。所以通常會使用.env.*.local
文件來覆蓋上述的配置, 另外會設置版本庫來忽略*.local
文件..env
通用的環境變量.env.development
開發環境的環境變量.env.production
生成環境的環境變量
對於開源項目通常還包括這些目錄:
- LICENSE: 說明項目許可
- .github: 開源貢獻規範和指南
- CONTRIBUTING: 貢獻指南, 這裡一般會說明貢獻的規範、以及項目的基本組織、架構等信息
- CODE_OF_CONDUCT: 行為準則
- COMMIT_CONVENTION: 提交信息規範,上文已經提及
- ISSUE_TEMPLATE: Issue的模板,github可以自動識別這個模板
- PULL_REQUEST_TEMPLATE: PR模板
任意一個優秀的開源項目都是你的老師,例如React、Vue…
4.2 目錄組織的風格
上面只是一個通用的項目組織規範,具體源代碼如何組織還取決於你們使用的技術棧和團隊喜好。網上有很多教程,具體可以搜索怎麼組織XX項目
. 總結一下項目組織主要有三種風格:
- Rails-style: 按照文件的類型劃分為不同的目錄,例如
components
、constants
、typings
、views
. 這個來源於Ruby-on-Rails框架,它按照MVC架構來劃分不同的目錄類型,典型的目錄結構如下: app models # 模型 views # 視圖 controllers # 控制器 helpers # 幫助程序 assets # 靜態資源 config # 配置 application.rb database.yml routes.rb # 路由控制 locales # 國際化配置 environments/ db # 數據庫相關 複製代碼 - Domain-style: 按照一個功能特性或業務創建單獨的目錄,這個目錄就近包含多種類型的文件或目錄. 比如一個典型的Redux項目,所有項目的文件就近放置在同一個目錄下: Users/ Home/ components/ actions.js actionTypes.js constants.js index.js model.js reducer.js selectors.js style.css index.js rootReducer.js 複製代碼
- Ducks-style: 優點類似於Domain-style,不過更徹底, 它通常將相關聯的元素定義在一個文件下。Vue的單文件組件就是一個典型的例子,除此之外Vuex也是使用這種風格: <template> <div id="app"> <h1>My Todo App!</h1> <TodoList/> </div> </template> <script> import TodoList from './components/TodoList.vue' export default { components: { TodoList } } </script> <style lang="scss"> @import './variables.scss'; /* … */ </style> 複製代碼
大部分情況下, 我們都是使用混合兩種方式的目錄結構,例如:
src/ components/ # ? 項目通用的『展示組件』 Button/ index.tsx # 組件的入口, 導出組件 Groups.tsx # 子組件 loading.svg # 靜態資源 style.css # 組件樣式 ... index.ts # 到處所有組件 containers/ # ? 包含'容器組件'和'頁面組件' LoginPage/ # 頁面組件, 例如登錄 components/ # 頁面級別展示組件,這些組件不能復用與其他頁面組件。 Button.tsx # 組件未必是一個目錄形式,對於一個簡單組件可以是一個單文件形式. 但還是推薦使用目錄,方便擴展 Panel.tsx reducer.ts # redux reduces useLogin.ts # (可選)放置'邏輯', 按照?分離邏輯和視圖的原則,將邏輯、狀態處理抽取到hook文件 types.ts # typescript 類型聲明 style.css logo.png message.ts constants.ts index.tsx HomePage/ ... index.tsx # ?應用根組件 hooks/ # ?可復用的hook useList.ts usePromise.ts ... index.tsx # 應用入口, 在這裡使用ReactDOM對跟組件進行渲染 stores.ts # redux stores contants.ts # 全局常量 複製代碼
框架官方很少會去干預項目的組織方式,讀者可以參考下面這些資源來建立自己項目組織規範:
- Redux 常見問題:代碼結構
- react-boilerplate
- vuex 項目結構
- React組件設計實踐總結02 – 組件的組織
4.3 腳手架和項目模板
在將項目結構規範確定下來後,可以創建自己的腳手架工具或者項目模板,用於快速初始化一個項目或代碼模板。
相關資源:
- yeoman – 老牌的項目腳手架工具
- plop – 代碼生成輔助CLI
- hygen – 類似於plop
- generact – 生成React組件, 大部分組件的文件結構差不多, 這個工具就是幫助你生成這些重複的代碼
- babel-code-generator – 利用babel來實現更高級的代碼編輯和自動生成
5 編碼規範
網絡上大部分『前端規範』指的都是編碼規範, 這是一種『狹義』的前端規範.
統一的編碼規範對團隊項目的長遠維護不無裨益. 一致性的代碼規範可以增強團隊開發協作效率、提高代碼質量、減少遺留系統維護的負擔。
最直接的好處就是避免寫出糟糕的代碼, 糟糕的代碼與新手和老手關係不大,我也見過好處工作很多年的『資深』工程師寫出噁心的代碼. 這樣的代碼隨着項目的迭代會變得難以控制。
現代的Lint工具已經非常先進,幾乎可以約束各種編碼行為. 比如約束一個文件的長度、函數的複雜度、命名規範、注釋規範、接口黑名單、DeadCode、檢查簡單的邏輯錯誤…
每一個程序員心目中對『好代碼』都有自己的主見,統一的編碼規範可以像秦始皇統一戰國一樣,避免不必要的論戰和爭議。
其實與其自己建立前端編碼規範,筆者推薦選擇社區沉澱下來的規範. 這方面的資源非常多,所以本文也不武斷地提出自己的規範建議. 推薦下面這些資源:
5.1 Javascript
- Lint工具
- ESLint – ?目前是社區最流行的、通用的Javascript Lint工具,Lint界的Babel。支持定製插件、preset。如果不想折騰可以選擇它的一些預定義配置
- TSLint – Typescript Lint工具。不過即將廢棄了, 推薦使用ESLint
- 規範
- JavaScript Standard Style – ? 零配置的、『標準』的Javascript編碼規範. 底層基於Eslint。目前不支持Typescript
- Airbnb JavaScript Style Guide – Airbnb的編碼規範,業界標杆
- 類型檢查. 暫時將它們歸類到這裡,因為它們同屬於『靜態測試』
- Typescript – ? Javascript語言的超集,這是一門『新』的語言,而不是簡單的類型檢查器. 不過它也支持原生Javascript的類型檢查
- Flow – Facebook出品的類型檢查器,語法和Typescript類似. 個人推薦使用Typescript
5.2 HTML
- Lint工具
- HTMLHint
- bootlint
- 規範
- Code Guide
5.3 CSS
- Lint工具
- stylelint – ? 通用的CSS編碼檢查工具,支持最新的CSS語法、CSS-in-js、以及其他類CSS語法(如SCSS、Less). 它也有預定義配置,推薦使用
- 規範
- Airbnb CSS / Sass Styleguide
- Code Guide
- 更多
- 方法論
- BEM – ? BEM命名規範
- OOCSS
- smacss
關於CSS可以學習Bootstrap這些傳統UI框架,他們的代碼組織性非常好, 值得學習
5.4 代碼格式化

- Prettier – ? 關於代碼格式化的所有東西都交給它吧!
基本上,所有代碼格式相關的工作都可以交給Prettier來做,在這個基礎上再使用Eslint覆蓋語義相關的檢查
5.5 集大成的
- isobar 前端代碼規範及最佳實踐
- 凹凸實驗室代碼規範
- 百度FEX規範
- 老牌的NEC規範 – 有點老
5.6 特定框架風格指南
- vue-style-guide
- Airbnb React/JSX Style Guide
- React組件設計實踐總結 – 自薦一下筆者寫的React組件設計相關實踐
5.7 Code Review

上述的Lint工具和類型檢查器, 可以約束代碼風格、避免低級的語法錯誤。但是即使通過上面的Lint和類型檢查,代碼也可能未必是『好代碼』。
很多代碼設計的『最佳實踐』是無法通過具象化的自動化工具或文檔覆蓋的, 這時候,'經驗'或者'群體智慧'就派上用場了. 比如Code Review階段會檢查這些東西:
- 編程原則、設計思想. 例如符合SOLID原則? 是否足夠DRY?接口設計是否簡潔易擴展、
- 模塊耦合程度、代碼重複
- 代碼健壯性。是否存在內存泄露、是否線程安全、是否有潛在性能問題和異常、錯誤是否被處理
- 代碼的性能和效率。
- 是否有沒有考慮到的場景?
如果你們是第一次推行Code Review, 可以建立一個檢查列表,對照着進行檢查。熟練後,心中自然無碼。
Code Review有很多好處,比如:
- Code Review可以讓其他成員都熟悉代碼。這樣保證其他人都可以較快地接手你的工作,或者幫你解決某些問題
- 提高代碼質量。毫無疑問. 一方面是主動性的代碼質量提升,比如你的代碼需要被人Review,會自覺盡量的提高代碼質量;另一方面,其他成員可以檢查提交方的代碼質量
- 檢查或提高新成員的編程水平。培養新人時,由於不信任它們提交的代碼,我們會做一次Review檢查代碼是否過關。另一方面這是一次真實的案例講解, 可以較快提高他們的能力
Code Review有兩種方式: 一個提交時
、一個是定時
:
提交時
. 大部分開源項目採用這種方式。通俗講就是Pull Request。只有代碼通過測試、和其他成員的Review才可以合進正式版本庫。這種方式也稱為『阻塞式』代碼檢查,一般配合GitFlow使用。定時
. 在項目完結後、項目的某個裡程碑、或者固定的時間(每天、每個星期..). 團隊成員聚在一起,回顧自己寫的代碼, 讓其他成員進行審查
Code Review是比較難以推行的,不過這個也要看你們團隊的情況,向我們錢少活多的團隊,很少的時間去立馬去兼顧其他成員的代碼. 這時候定時Review
會更有用,因為看起來更『節省時間』.
而提交時Review
則可以針對新人,比如你不信任他們的代碼或者希望幫助他們提高編碼能力。
相關資源:
- Code Review最佳實踐
- 是否要做Code Review?與BAT資深架構師爭論之後的思考
- 一些Code Review工具
6 文檔規範
文檔對於項目開發和維護、學習、重構、以及知識管理非常重要。
和寫測試一樣、大部分開發人員會覺得寫文檔是一件痛苦的事情,不過只有時間能夠證明它的價值。比如對於人員流動比較大的公司,如果有規範的文檔體系,轉交工作就會變動非常輕鬆.
廣義的文檔不單指『說明文件』本身,它有很多形式、來源和載體,可以描述一個知識、以及知識形成和迭代的過程。例如版本庫代碼提交記錄、代碼注釋、決策和討論記錄、CHANGELOG、示例代碼、規範、傳統文檔等等
6.1 建立文檔中心
我們公司是做IM的,所以之前我們優先使用'自己的'通訊工具來分享文檔,這種方式有很大問題:
- 如果沒有存檔習慣(比如後端的API文檔,因為由後端維護,一般不會主動去存檔), 文檔就可能丟失,而且通訊工具是不會永久保存你的文檔的。當丟失文件就需要重新和文檔維護者索要
- 糟糕的是文檔維護者也是自己手動在本地存檔的,這樣導致的問題是: 如果工作轉交,其他開發者需要花費一點時間來查找; 丟失了就真的沒了
- 每一次文檔更新要重新發一份, 這很麻煩,而且可能出現漏發的情況, 導致前後不一致.
- 關於知識的學習、以及有意義的討論記錄無法歸檔。
上面介紹的是一種非常原始的文檔共享方式,很多小團隊就是這麼乾的。
對於項目本身的文檔建議放置在關聯項目版本庫裏面,跟隨項目代碼進行迭代, 當我們在檢索或跟蹤文檔的歷史記錄時,這種方式是最方便的。
然而很多應用是跨越多個團隊的,每個團隊都會有自己的文檔輸出(比如需求文檔、系統設計文檔、API文檔、配置文檔等等),而且通常也不會在一個版本庫里。這時候文檔就比較分散。所以一個統一的文檔中心是很有必要。
我們公司現在選擇的方案是Git+Markdown
,也就是說所有的文檔都放置在一個git版本庫下。之前也考慮過商業的方案,譬如石墨文檔、騰訊文檔, 但管理層並不信任這些服務。
大概的git項目組織如下:
規範/ A應用/ 產品/ 設計/ API文檔/ 測試/ 其他/ B應用/ 複製代碼
Git版本庫(例如Gitlab)有很多優勢,例如歷史記錄跟蹤、版本化、問題討論(可以關聯issue、或者提交)、多人協作、搜索、權限管理(針對不同的版本庫或分組為不同人員設置權限)等等。
Git+Markdown
可以滿足開發者的大部分需求。但是Git最擅長的是處理純文本文件、對於二進制是無能為力的,無法針對這些類型的文檔進行在線預覽和編輯。
所以Git+Markdown
並不能滿足多樣化的文檔處理需求,比如思維導圖、圖表、表格、PPT、白板等需求. 畢竟它不是專業的文檔處理工具。所以對於產品、設計人員這些富文檔需求場景,通常會按照傳統方式或者更專業的工具對文檔進行管理.
6.2 文檔格式
毫無疑問,對於開發者來說,Markdown是最適合的、最通用的文檔格式。支持版本庫在線預覽和變更歷史跟蹤。
下面這些工具可以提高Markdown的開發效率:
- 可視化編輯器
- Visual Code: 大部分代碼編輯都支持Markdown編輯和預覽
- Mou: Mac下的老牌編輯器
- typora: 跨平台的Markdown編輯器,推薦
- markdownlint: 編碼檢查器
- 擴展(Visual Studio Code):
- Markdown All in One: All you need to write Markdown (keyboard shortcuts, table of contents, auto preview and more)
- Markdown TOC: markdown 目錄生成,我最常用的markdown插件
- 圖表繪製工具:
- drawio 基於Web的圖表繪製工具、也有離線客戶端
- KeyNote/PPT 臨時繪圖也不錯
6.3 定義文檔的模板
關於如何寫好文檔,很難通過標準或規範來進行約束,因為它的主觀性比較強, 好的文檔取決於編輯者的邏輯總結能力、表達能力、以及有沒有站在讀者的角度去思考問題。
所以大部分情況下,我們可以為不同類型的文檔提供一個模板,通過模板來說明一個文檔需要包含哪些內容, 對文檔的編寫者進行引導.
例如一個API文檔可能需要這些內容:
- 接口的索引
- 接口的版本、變更記錄
- 用法和整體描述, 認證鑒權等等
- 描述具體的接口
- 功能說明
- 方法名稱或者URI
- 參數和返回值定義
- 調用示例
- 注意事項等等
具體規範內容因團隊而異,這裡點到為止.
擴展:
- 中文技術文檔的寫作規範
- React RFC模板
6.4 討論即文檔
一般情況下,對於一個開源項目來說除了官方文檔,Issues也是一個很重要的信息來源。在Issue中我們可以獲取其他開發者遇到的問題和解決方案、給官方反饋/投票、關注官方的最新動態、和其他開發者頭腦風暴唇槍舌戰等等。
所以相對於使用IM,筆者更推薦Issue這種溝通模式,因為它方便歸檔組織,索引和查找。而IM上的討論就像流水一樣,一去不復返。
當然兩種工具的適用場景不一樣,你拿IM的使用方式來使用Issue,Issue就會變得很水。Issue適合做有意義的、目的明確的討論。所以要譴責一下在Github Issue上灌水的開發者。
關於Issue有很多妙用,推薦閱讀這篇文章<如何使用 Issue 管理軟件項目?>
現在很多開源項目都引入了RFC(請求意見稿)流程(參考React採用新的RFC流程, 以及Vue 最黑暗的一天), 這讓開發者有『翻身農奴、當家做主』的感覺,任何人都可以參與到一個開源項目重大事件的決策之中。每個RFC會說明決策的動機、詳細設計、優缺點。除了官方文檔之外,這些RFC是很有價值的學習資料。
我覺得如果不涉及機密,團隊應該要讓更多人參與到項目的設計和決策中,對於新手可以學到很多東西,而對於發起者也可能有考慮不周的情況。
那對於企業應用開發, Issue有用嗎?
當然有用, 比如我們可以將這類話題從IM轉移到Issue:
- 設計方案
- 決策/建議
- 新功能、新技術引入
- 重構
- 性能優化
- 規範
- 問題討論
- 重大事件
- 計劃或進度跟蹤
- …
另外Issue通常通過標籤來進行分類,方便組織和檢索:

6.5 注釋即文檔
必要和適量的注釋對閱讀源代碼的人來說就是一個路牌, 可以少走很多彎路.
關於注釋的一些準則,<阿里巴巴Java開發手冊>總結得非常好, 推薦基於這個來建立注釋規範。另外通過ESlint是可以對注釋進行一定程度的規範。
6.6 代碼即文檔
現在有很多種工具支持從代碼中解析和生成文檔, 這可以給開發者簡化很多文檔維護的工作。
舉個例子,我們經常會遇到修改了代碼,但是文檔忘記同步的情況。通過『代碼即文檔』的方式至少可以保持文檔和代碼同步更新;另外很多工具會分析代碼的數據類型,自動幫我們生成參數和返回值定義,這也可以減少很多文檔編寫工作以及出錯率。
比如可以通過下面注釋方式來生成組件文檔:
import * as React from 'react'; import { Component } from 'react'; /** * Props注釋 */ export interface ColumnProps extends React.HTMLAttributes<any> { /** prop1 description */ prop1?: string; /** prop2 description */ prop2: number; /** * prop3 description */ prop3: () => void; /** prop4 description */ prop4: 'option1' | 'option2' | 'option3'; } /** * 對組件進行注釋 */ export class Column extends Component<ColumnProps, {}> { render() { return <div>Column</div>; } } 複製代碼
相關的工具有:
- API文檔
- jsdoc Javascript文檔注釋標準和生成器
- tsdoc Typescript官方的注釋文檔標準
- typedoc 基於tsdoc標準的文檔生成器
- Typescript
- Javascript
- 後端接口文檔
- Swagger Restful接口文檔規範
- GraphQL: 這個有很多工具,例如graphiql, 集成了Playground和文檔,很先進
- Easy Mock 一個可視化,並且能快速生成模擬數據的服務
- 組件文檔
- vue-styleguidist
- 有更好的工具請評論告訴我
- Docz
- Styleguidist
- StoryBook 通用的組件開發、測試、文檔工具
- React
- Vue
7 UI設計規範

這是一個容易被忽略的規範類型。筆者就深受其苦,我們公司初期UI並不專業,沒有所謂的設計規範,這就導致他們設計出來的產品都是東借西湊,前後不統一,多個應用之間的組件不能復用。這搞得我們不得不浪費時間,寫很多定製化樣式和組件,為他們的不專業買單.
關於UI設計規範的重要性有興趣的讀者可以看這篇文章<開發和設計溝通有多難?- 你只差一個設計規範>.
簡單總結一下UI設計規範的意義:
- 提供團隊協作效率(產品和開發)
- 提高組件的復用率. 統一的組件規範可以讓組件更好管理
- 保持產品迭代過程中品牌一致性
建立一個定義良好的設計規範需要UI設計和開發
的緊密配合,有時候也可以由我們前端來推動。
比如很多開源的UI框架,一開始都是開發者YY出來的,並沒有設計參與,後來組件庫慢慢沉澱成型,UI設計師才介入規範一下。
如果你們團隊不打算制定自己的UI設計規範,則推薦使用現成的開源組件庫:
- Ant Design
- Material-UI
- Element UI
- WeUI
- Microsoft Fabric
這些開源組件庫都經過良好的設計和沉澱, 而且配套了完善的設計原則、最佳實踐和設計資源文件(Sketch 和 Axure),可以幫助業務快速設計出高質量的產品原型。
8 測試規範
測試是保障代碼質量的重要手段,但是很少有人願意在這裡花太多時間。
比如筆者,我很少會去給業務代碼和組件寫單元測試,除非自己對代碼非常沒有信心,按照我的理念寫測試不如將代碼寫得更簡單一點,比如把一個函數拆分為更小的函數,保持單一職責。
但是對於一些底層、共享的代碼模塊還是有測試的必要的。
我在不知道測試什麼?這些是你需要知道的軟件測試類型和常識文章中,列舉了一些開發者需要關注的測試類型和常識, 如果按照測試的階段進行分類,大概是這樣子的:

其中前端開發者需要關注的主要有以下幾種測試類型:
- 單元測試: 對獨立的軟件模塊進行測試
- UI組件測試: 包括了快照(Snapshot)測試
- 集成測試: 在單元測試的基礎上,將模塊組合起來,測試它們的組合性
- E2E測試: 在完整、真實的運行環境下模擬真實用戶對應用進行測試。主要測試前端和後端的協調性
- 兼容性測試: 上面提到了瀏覽器兼容規範,在將版本提交給測試/發佈之前,需要確保能符合兼容性要求
- 性能測試: 測試和分析是否存在性能問題
- 其他:
- 安全測試
- SEO測試
因為對於小公司來說整個軟件開發流程可能沒有那麼規範,比如很難構建一個完整的端對端測試環境,這些都不是前端團隊可以操作的範圍, 所以自動化測試很難推行。但是可以根據團隊和業務情況逐步進行開展。
可實施性比較高的, 也比較簡單是單元測試,所以本文也重點關注單元測試.
8.1 測試的流程
首先要定義一個合適的軟件測試流程, 合適的測試流程可以降低開發和測試團隊之間的溝通協作成本、提高測試效率。例如我們團隊目前的測試流程:

8.2 單元測試
單元測試有很多好處, 比如:
- 提高信心,適應變化和迭代. 如果現有代碼有較為完善的單元測試,在代碼重構時,可以檢驗模塊是否依然可以工作, 一旦變更導致錯誤,單元測試也可以幫助我們快速定位並修復錯誤
- 單元測試是集成測試的基礎
- 測試即文檔。如果文檔不能解決你的問題,在你打算看源碼之前,可以查看單元測試。通過這些測試用例,開發人員可以直觀地理解程序單元的基礎API
- 提升代碼質量。易於測試的代碼,一般都是好代碼
測什麼?
業務代碼或業務組件是比較難以實施單元測試的,一方面它們比較多變、另一方面很多團隊很少有精力維護這部分單元測試。所以通常只要求對一些基礎/底層的組件、框架或者服務進行測試, 視情況考慮是否要測試業務代碼
測試的準則:
- 推薦Petroware的Unit Testing Guidelines, 總結了27條單元測試準則,非常受用.
- 另外<阿里巴巴的Java開發手冊>中總結的單元測試準則, 也不錯,雖然書名是Java,準則是通用的.
單元測試指標:
一般使用測試覆蓋率
來量化,儘管對於覆蓋率能不能衡量單元測試的有效性存在較多爭議。
大部分情況下還是推薦儘可能提高覆蓋率, 比如要求語句覆蓋率達到70%;核心模塊的語句覆蓋率和分支覆蓋率都要達到100%
. 視團隊情況而定
擴展:
- 測試覆蓋(率)到底有什麼用?
相關工具
- Headless Browsers: 無頭瀏覽器是網頁自動化的重要運行環境。常用於功能測試、單元測試、網絡爬蟲
- puppeteer
- Headless Chromium
- 測試框架
- 組件測試
- testing-library ?
- Enzyme
- Jest ?Facebook的單元測試框架. 零配置, 支持組件快照測試、模塊Mock、Spy. 一般場景, 單元測試學它一個就行了
- Intern
- 單元測試
- AVA
- Jasmine
- Mocha
- Tape
- 斷言庫
- Chai
- expect.js
- should.js
- Mock/Stubs/Spies
- sinon.js
- 代碼覆蓋率
- istanbul
- 基準測試
- benchmark.js
- jsperf.com
9 異常處理、監控和調試規範
很多開發者常常誤用或者輕視異常的處理, 合理有效的異常處理可以提高應用的健壯性和可用性,另外還可以幫助開發者快速定位異常.
9.1 異常處理
<阿里巴巴的Java開發手冊>中總結的異常處理規範對JavaScript的異常處理也很有參考意義,比如:
- 異常不要用來做流程控制,條件控制。
- 捕獲異常是為了處理它,不要捕獲了卻什麼都不處理而拋棄之,如果不想處理它,請將該異常拋給它的調用者。最外層的業務使用者,必須處理異常,將其轉化為用戶可以理解的內容。
- catch時請分清穩定代碼和非穩定代碼,穩定代碼指的是無論如何不會出錯的代碼。對於非穩定代碼的catch儘可能進行區分異常類型,再做對應的異常處理。不要對大段代碼進行try-catch
- …
然後再根據JavaScript本身的異常處理特點總結一些規範行為, 例如:
- 不要throw非Error對象
- 不要忽略異步異常
- 全局監控Javascript異常
- …
資源:
- 從1000+個項目中總結出來的前10個JavaScript錯誤, 以及如何避免它們
- Javascript異常處理『權威』指南
- 前端異常處理最佳實踐
9.2 日誌
對於前端來說,日誌也不是毫無意義(很多框架性能優化建議在生產環境移除console)。尤其是在生產現場調試代碼時,這時候可貴的控制台日誌可以幫助你快速找到異常的線索.
不過通常我們只要保留必要的、有意義的日誌輸出,比如你不應該將console.log放到一個React渲染函數中、或者放到一個循環中, DDos式的日誌信息並不能幫助我們定位問題,反而會影響運行的性能. 所以需要一個規範來約束日誌輸出行為, 比如:
- 避免重複打印日誌
- 謹慎地記錄日誌, 劃分日誌級別。比如生產環境禁止輸出debug日誌;有選擇地輸出info日誌;
- 使用前綴對日誌進行分類, 例如:
[User] xxxx
- 只記錄關鍵信息, 這些信息可以幫助你診斷問題
- …
擴展資源
- debug 適合Node.js和瀏覽器的debug日誌工具, 支持動態開啟日誌打印
- vConsole 移動端調試利器
9.3 異常監控
因為程序跑在不受控的環境,所以對於客戶端應用來說,異常監控在生產環境是非常重要的,它可以收集各種意料之外生產環境問題,幫助開發者快速定位異常。
異常監控通常會通過三種方式來收集異常數據:
- 全局捕獲。例如使用window.onerror, 或者
unhandledrejection
- 主動上報。在try/catch中主動上報.
- 用戶反饋。比如彈窗讓用戶填寫反饋信息.
和日誌一樣,不是所有『異常』都應該上報給異常監控系統,譬如一些預料之內的『異常』,比如用戶輸入錯誤、鑒權失敗、網絡錯誤等等. 異常監控主要用來上報一些意料之外的、或者致命性的異常.
要做好前端的異常監控其實並不容易,它需要處理這些東西:
- 瀏覽器兼容性。
- 碎片收集(breadcrumbs)。收集『災難』現場的一些線索,這些線索對問題診斷很重要。例如當前用戶信息、版本、運行環境、打印的日誌、函數調用棧等等
- 調用棧的轉換。通常在瀏覽器運行的壓縮優化過的代碼,這種調用棧基本沒什麼可讀性,通常需要通過SourceMap映射到原始代碼. 可以使用這個庫: source-map
- 數據的聚合。後端監控系統需要對前端上報的信息進行分析和聚合
對於小團隊未必有能力開發這一套系統,所以推薦使用一些第三方工具。例如
- Sentry ?免費基本夠用
- FunDebug 付費增強
擴展:
- 前端異常監控解決方案研究
- 搭建前端監控系統
10 前後端協作規範
前端是Web的一個細分領域,往往不能脫離後端而存在。所以和後端協作的時間是最長的.
10.1 協作流程規範
前後端團隊經過長期的合作,一般可以總結出一條對於雙方開發效率最優的協作流程. 將這個落實為規範,後面的團隊成員都遵循這個步調進行協作。
一個典型的前後端協作流程如下:

- 需求分析。參與者一般有前後端、測試、以及產品. 由產品主持,對需求進行宣貫,接受開發和測試的反饋,確保大家對需求有一致的認知
- 前後端開發討論。討論應用的一些開發設計,溝通技術點、難點、以及分工問題.
- 設計接口文檔。可以由前後端一起設計;或者由後端設計、前端確認是否符合要求
- 並行開發。前後端並行開發,在這個階段,前端可以先實現靜態頁面; 或者根據接口文檔對接口進行Mock, 來模擬對接後端接口
- 在聯調之前,要求後端做好接口測試
- 真實環境聯調。前端將接口請求代理到後端服務,進行真實環境聯調。
10.2 接口規範
首先應該確定下來的是接口規範。其實使用哪種接口標準是其次,重要的是統一,且要滿足前後端的開發效率要求.
筆者不建議後端去定義自己的接口標準,而應該去選擇一些通用的、有標準定義接口形式, 例如:
- RESTful: RESTful是目前使用最為廣泛的API設計規範, 基於HTTP本身的機制來實現. 筆者個人是比較喜歡這個API規範,但是我發現很多開發者並不能真正(或者說沒心思)理解它,設計出來的接口,跟我想像的相差甚遠。換句話說,對於RESTful,開發者之間很難達成一致的理解,容易產生分歧。 因為是使用最廣泛的API形式,所以社區上有很多工具來對RESTful接口進行文檔化、測試和模擬.
- JSONRPC 這是一種非常簡單、容易理解的接口規範。相對於RESTful我更推薦這個,簡單則不容易產生分歧,新手也可以很快接受.
- GraphQL ?更為先進、更有前景的API規範。但是你要說服後端配合你使用這種標準可能很有難度
接口設計需要注意的點:
- 明確區分是正常還是異常, 嚴格遵循接口的異常原語. 上述接口形式都有明確的異常原語,比如JSONRPC,當出現異常時應該返回
錯誤對象
響應,而不是在正常的響應體中返回錯誤代碼. 另外要規範化的錯誤碼, HTTP響應碼就是一個不錯的學習對象 - 明確數據類型。很多後端寫的接口都是string和number不分的,如果妥協的話、前端就需要針對這個屬性做特殊處理,這也可能是潛在的bug
- 明確空值的意義。比如在做更新操作是,空值是表示重置,還是忽略更新?
- 響應避免冗餘的嵌套。
- 接口版本化,保持向下兼容。就像我們上文的『語義化版本規範』說的,對於後端來說,API就是公共的接口. 公共暴露的接口應該有一個版本號,來說明當前描述的接口做了什麼變動,是否向下兼容。現在前端代碼可能會在客戶端被緩存,例如小程序。如果後端做了break change,就會影響這部分用戶。
10.3 接口文檔規範
後端通過接口文檔向前端暴露接口相關的信息。通常需要包含這些信息:
- 版本號
- 文檔描述
- 服務的入口. 例如基本路徑
- 測試服務器. 可選
- 簡單使用示例
- 安全和認證
- 具體接口定義
- 方法名稱或者URL
- 方法描述
- 請求參數及其描述,必須說明類型(數據類型、是否可選等)
- 響應參數及其描述, 必須說明類型(數據類型、是否可選等)
- 可能的異常情況、錯誤代碼、以及描述
- 請求示例,可選
人工維護導致的問題:
上文『代碼即文檔』就提到了人工維護接口文檔可能導致代碼和文檔不同步問題。
如果可以從代碼或者規範文檔(例如OpenAPI這類API描述規範)中生成接口文檔,可以解決實現和文檔不一致問題, 同時也可以減少文檔編寫和維護的投入.
10.4 接口測試與模擬
為了做到高效率的前後端並行開發,接口的測試與模擬是必要的。
- 前端要求後端在聯調之前,需要測試驗證好自己的接口是否可以正常工作。而不是在聯調期間,把前端當『接口測試員』,阻塞接口聯調進度
- 另外前端需要在後端接口未準備好之前,通過接口模擬的方式,來編寫業務邏輯代碼。
針對接口測試與模擬,存在下圖這樣一個理想的模型:

一切從定義良好的接口文檔出發,生成Mock Server
和Mock Client
, Mock Server給前端提供模擬數據,而Mock Client則輔助後端對它們的接口進行測試.
資源:
- RESTful
- Swagger 這是最為接近上面理想模型的一個解決方案
- JSON Server 快速生成JSON mock服務器
- Easy Mock 可視化的、在線的接口mock服務
- GraphQl
- GraphQL Faker
- graphql-tools
- 模擬數據生成
- faker.js ?強大的模擬數據生成工具,支持Node和瀏覽器
- Mock.js 數據生成和模擬工具
11 培訓/知識管理/技術沉澱
我覺得一個團隊的知識管理是非常重要的. 你要問一個剛入行的新手加入團隊希望得到什麼?很多人的回答是'學習', 希望自己的技術可以更加精進, 錢倒還是其次。
然而現實是目前很多公司的氛圍並不是這樣的,一天到晚寫業務代碼、工作量大、每天做重複的事情,而且還加班,工作多年技術也沒感覺有多少進步, 確實會讓人非常沮喪。包括筆者也是這樣的。
所以為了改善這種情況,我來聊聊最近在『小團隊』做的一些嘗試.
11.1 新人培訓
如果團隊有規範的新成員培訓手冊,可以節省很多培訓的時間,避免每次重複口述一樣的內容。培訓手冊包含以下內容:
產品架構與組織架構. 介紹公司背景和產品,一般組織的團隊結構和產品的架構是相關聯的. 以筆者所在公司為例, 主要產品是即時通信:

產品研發流程: 介紹產品開發和迭代會涉及到的流程、以及團隊之間的協作銜接,例如:

- 工作範圍: 團隊成員的職責範圍
- 建立資源索引: 開發需要設計到的資源,比如各種文檔地址、研發系統入口(例如gitlab、bug跟蹤系統、文件共享、發佈平台、開發/測試環境、監控系統)、協作規範等等。將這些資源整理好可以減少不必要的溝通成本
- 規範: 即本文的主體'前端協作規範'。有規範可循,可以讓成員以較快的速度入手開發、同時也減少培訓成本投入。
培訓手冊將可以文檔具象化的內容整理為文檔,和上文說到的Code Review一樣,一些東西無法通過文檔來說明,所以我們一般會搭配一個『培訓導師』,在試用期間,一對一輔導。
11.2 營造技術氛圍
- 鼓勵成員寫技術博客,或者建立自己的團隊專欄. 寫一篇好的文章不容易
- 鼓勵參與開源項目
- 建立面試題庫 組織一起解一些面試題或算法題,加深對知識點的理解
- 定期的專題分享. 鼓勵團隊成員定期進行專題學習和研究,編寫技術博客,並將學習的成果分享給其他成員. 這是一種抱團取暖的學習方式,旨在幫助團隊成員一起學習和成長。 比如開發老手可以分享自己的經驗,研究更深層次的技術;新手則可以研究某些開發技巧、新技術,例如CSS Grid,svg動畫等等。推薦團隊成員有個明確的研究領域,這樣分工合作可以學習到更多東西. 專題怎麼來?
- 專題請求. 可以請求其他成員完成專題,比如比較深的知識,可以要求團隊比較有經驗的進行學習分享
- 學習總結.
- 項目回顧
- 難點攻克
- 項目規範
- 工具使用
- 落實和完善開發規範. 規範本身就是團隊知識沉澱的一種直接輸出
- 圖書分享. 和離散的文章或教程相比,圖書的知識會比較系統,另外很多經典的圖書是要靜下來好好欣賞的。
- 鼓勵重構和持續優化代碼
- 抽象一套基礎庫或框架,減少重複工作, 提高工作效率. 不加班先從提高工作效率開始