可能很多人和我一樣, 首次聽到"前端架構"這個詞, 第一反應是: "前端還有架構這一說呢?" 在后端開發領域, 系統規劃和可擴展性非常關鍵, 因此架構師備受重視, 早在開發工作啟動之前, 他們就被邀請加入到項目中, 而且他們會跟客戶討論即將建成的平臺的架構要求, 使用還什么技術棧? 內容類型是什么? 這些內容如何被創建?軟件架構師的職責就是要保證項目中每一步都在總體架構的指導下進行, 而不會隨機決定.
現在的前端領域, 隨著JS框架, UI框架和各種庫的豐富, 前端架構也變得十分的重要. 如果一個大型項目沒有合理的前端架構設計, 那么前端代碼可能因為不同的開發人員隨意的引入各種庫和UI框架, 導致代碼量變得異常臃腫, 最終結果可能是代碼變得無法維護, 頁面性能低下,不得已只能推翻重構. 所以我們需要在項目開始前, 同樣的需要對前端代碼進行架構, 一旦前端架構師設計出所有前端開發人員都要遵循的檢驗機制, 建立起系統設計的規范, 那么項目就擁有了可以衡量代碼質量的標準, 前端開發人員也能享受到更高效的工作流. 所以, 前端架構的定義可以用以下一句話來總結:
前端架構是一系列工具和流程的集合, 旨在提升前端代碼的質量, 并實現高效, 可持續的工作流.
本系列的前端架構文章, 將分別圍繞前端架構的四個核心展開, 分別是代碼, 流程, 測試, 文檔.
前端架構的四個核心
(一) 代碼
歸根到底, 所有的網站都是由一堆文本文件和資源文件組成的. 當我們面對制作網站所產生的大量代碼時, 就會發現為代碼和資源設定一個期望是多么重要. 在代碼部分, 我們會專注于如果實現系統架構中的HTML, CSS, JavaScript.
(二) 流程
現在早已過了FTP上傳文件的時代, 那么現在重要的是思考怎么用工具和流程構建一個高效且避免出錯的工作流. 工作流變得越來越復雜, 那些用于它們的工具也同樣如此. 這些工具在提高生產力, 加快效率和保持代碼一致性上帶來了驚人的效果, 但也伴隨著過度工程化和抽象化的風險. 所以, 現有的工作流是需要改變的.
(三) 測試
要構建一個可擴展和可持續優化的系統, 必須保證新代碼和老代碼能夠很好的兼容. 我們的代碼不會獨立存在, 它們都是大型系統中的一部分. 創建覆蓋面廣泛的測試方案, 能確保老代碼還能正常運作.
(四) 文檔
一般而言, 如果不是團隊中的重要成員要離開, 我們幾乎都不會意識到文檔的重要性. 等到那個時候, 大家將不得不停下手頭的工作, 優先編寫所有的文檔. 作為前端機構師, 你要善于在項目開發的同時編寫良好的文檔.
流程核心
現在的前端工作流程已經發生了很大的改變, 最開始的Web開發階段, 一般的工作流程是根據郵件交流來理解客戶的需求, 然后通過FTP登錄他們的服務器, 對網站代碼做必要的修改. 這種做法是非常不成熟的. 如果誤解了郵件的內容, 改錯了代碼, 會發生什么呢? 如果修改了一部分css代碼, 導致破壞了很多頁面的布局呢? 如果我改掉一個JavaScript的bug, 但又引發兩個bug呢?
經過多年的項目開發, 現在已有了一整套成熟的開發流程, 一般公司的開發流程為以下幾個步驟:
- PM(產品經理)提出需求,并和開發人員討論需求的具體細節和可行性
- 需求確定之后, 發布出原型圖和需求文檔
- 開發人員根據原型圖和需求文檔進行開發, 前端還需要UI(網頁設計人員)提供設計圖, 項目總監使用JIRA等項目管理工具來跟蹤工作流
- 搭建測試環境來測試代碼, 開發人員完成功能開發并自測通過后, 提交給測試人員進行測試
- 測試人員和需求方通過后, 將代碼合并到遠程的master分支, 并部署上線
下面將分別從每個步驟討論其它們在現代化開發流程中的必要性:
(一)需求
提出需求是進行開發的初始工作, PM提出了明確的需求后. FE(前端開發人員)才能進行開發. 當然, 互聯網行業中對于提出需求是否需要開發人員參與討論是有不同的爭議的, 有的人認為讓開發人員參與需求階段, 可能會因為開發人員的技術認知水平和慣性思維等因素, 限制PM提出一個有創意的需求. 也有的人認為應當讓開發人員參與需求討論, 因為可能因為PM完全不懂技術, 導致提出根本無法實現的需求.
毫無疑問, PM比起開發人員更加懂得需求, 因為他們會在告知開發人員需求之前完成需求收集, 需求描述, 需求全景圖, 需求分析, 用戶故事等一系列專業化的工作 . 但我贊同開發人員同時也在需求上能有一定的話語權, PM在需求表達階段讓UI, FE, BE(后端開發人員)參與討論, 不僅能讓開發人員更好的理解需求, 也可能讓PM發現一些忽視的點, 從而更好的提出一個完整的方案.
(二)原型
原型圖是現代開發流程中不可或缺的一環, 它對于項目中的每個角色都有著重要的意義:
- PM進行需求驗證的方式: PM在使用Axure畫原型圖的過程也是自己構思產品的過程, 經過原型圖能夠使得PM更加的理解產品.
- 給需求方確認需求的工具: PM理解的需求可能和需求方的需求是有出入的, 設計出原型圖作給需求方來驗證需求的正確性是十分必要的.
- UI設計出設計圖的依舊: 原型幾乎有了整個界面的雛形, 拿到原型圖后, UI能夠更好的根據原型圖和PM討論其設計樣式, 更快的交付出設計圖給FE, 極大的降低了溝通成本.
- 開發人員開發的依據: 初級的前端可能只會拿著設計圖進行切圖, 很可能切完圖之后, 發現功能完全添加不進去的情況. 有經驗的前端都會同時拿著設計圖和原型圖進行開發. 通過設計圖在寫
html
和css
的同時通過原型圖去寫js的業務邏輯部分. 同時, 原型圖也是后端開發人員提供業務接口的依據. - 測試人員測試的依據: 作為一個現測試人員,可以從原型快速了解產品的核心功能,和頁面大致展現形式,方便測試人員提早了解需求,評估需求,制定測試計劃,分配測試任務,然后各自開始編寫測試用例
可以說, (一)(二)步驟是前端開發人員進行開發的前提, 原型其實也是為項目中各角色更好的理解需求而服務的. 下面, 我以一個例子, 來解釋一下什么叫做真正的理解需求.
需求場景假設
加入現在有個論壇的項目, 產品經理小C提了個需求"給論壇增加評論功能". 作為前端工程師的小A接到需求后, 該如何高質量的完成這個需求?
- 項目名稱: 興趣論壇
- 項目主要成員: 前端工程師小A, 后臺工程師小B, 產品經理小C
- 產品需求: 給論壇增加評論功能.
此時, 小A接到需求后, 腦海里可能浮現的是下面這張圖:
需求明確和需求確認
可能一些同學聽到需求后, 就著手開始進行開發了. 不就一個簡單的評論功能嗎? 一個<textarea>
, 加個<button>
, 在引入jQuery進行ajax
提交和DOM
的操作就搞定了. 作為一名有經驗的前端開發人員,要明白的是實際的項目并不是像寫demo那么隨意, 我們寫出來的代碼是要部署到線上環境給用戶使用的. 所以, 面對"給論壇增加評論功能"這樣的不明確的需求,是還需要進行需求明確和需求確認的.
1. 需求明確
想想我們平時在論壇或者微博里面見到的評論功能, 就真的是上圖所顯示的這么一個簡單<textarea>
和<button>
就能夠搞定的嗎? 是不是評論可能還有以下的功能:
- 是否需要支持富文本輸入?
- 是否需要支持微博, 微信朋友圈, qq空間的評論分享
- 發表評論后, 評論如何展示?
也許經過一番需求明確, 最終的需求會是下圖所示. 所以遇到需求不明確的情況, 一定要明確具體需求, 避免后期無意義的返工和延期.
2. 需求確認
需求已經明確了, 需要支持富文本輸入, 需要暫時評論, 這就足夠了嗎? 其實不夠, 作為一個有經驗的前端開發人員, 還有很多的細節需要確認, 比如:
- 評論最大支持輸入多少個字? (非常重要, 關乎后臺存儲方案的設計)
- 一個中文字符算1個字, 還是2個英文字母算一個字? (產品語言, 技術語言之間的溝通轉換)
- 輸入內容過長, 如何進行錯誤提示?(交互細節)
- 輸入內容過長時, 是否運行提交評論? 如允許, 是對評論內容進行截斷后提交?(容錯機制)
- 用戶未輸入內容的情況下, 評論框內默認提示文案是什么?(交互細節)
- .......
一個評論功能可能需要明確的需求有很多, 這里就不在更多的贅述了, 從這個例子可以看出, 如果不是十分懂技術的PM, 是很難提出一個明確的需求的. 所以作為開發人員的我們, 在明確了需求之后還需要進行需求確認, 而且可能是反復的進行需求確認.
(三)開發
1. 本地部署
如果公司沒有一套標準的本地部署流程的話, 那么它會成為你敲代碼前花費較多時間的一個部分, 可能包括拉取多個代碼庫, 配置服務器設置, 修改本機host或設置VPN. 不管流程是什么, 請一定要確保在README.md文件中說明每一步所對應的操作, 確保新的工程師能夠很快的通過git clone xxx
代碼之后, 就能夠將代碼在本地運行起來. 千萬不要低估README.md文件的重要性, 一個清晰的README.md文件可以讓一個新入職的工程師在Git的遠程倉庫上拉代碼之后幾分鐘就能運行起來. 當然, 對于一個依賴較多且配置項繁瑣的項目, 如果缺少一個清晰的README. md文件, 花費幾天的時間才在本地環境跑起來也是不足為奇的.
2. 創建功能分支
在多人開發的項目中, 是絕對不允許你直接在master分支下進行開發的, master分支有且只能用作保存上線版本的代碼, 在開發過程中, 應該針對每個功能點通過git checkout -b newBranchName
來創建一個新的功能分支, 在該功能分支上將該功能開發完畢并在本地進行了自測之后, 再將該功能分支merge
到dev分支上, dev分支主要用來合并功能分支代碼并交由測試人員進行測試, 當本次迭代所有的功能測試完畢之后, 才能夠將dev分支上的代碼merge
到master分支上, 并準備上線.
3. 使用自動化工具(Gulp, Webpack等)
如果有一定工作年限的前端開發者, 那么一定經歷過從Grunt轉移到Gulp, 并在近兩年轉移到Webpack的過程. 這類的自動化工具, 能夠極大的優化我們的工作流程, 幫助我們高效率的完成類似于自動刷新頁面, 壓縮CSS, JS和合并壓縮代碼等機械重復的體力活. 對于自動化工具對于開發人員的優點, 我看過下面這樣一句話說得很好:
每件事都是一個程序, 開發也像程序一樣, 每個步驟都是一段代碼, 當開發規模隨著文檔, 代碼, 需求而增加時, 重復的步驟變得越來越多. 此時, 如果可以像抽象代碼一樣抽象出一些相同操作就可以大大提升開發效率. 因此, 出現了更多優質的工具來代替人工做一些不斷重復的開發以減少程序員的工作量.
目前前端領域應該使用得最多的兩個自動化工具就是Gulp和Webpack. 這兩者在功能上有一定的區別, Gulp是一個自動化構建工具, 你可以通過豐富的插件在項目中自動的幫你執行常見的任務. Webpack是一個自動化打包工具, 通過一個入口文件, 將所有依賴的模塊打包成為一個js文件, 當然你也可以通過code spliting將其切分為多個js文件, 按需加載以提高效率.
目前主流的前端框架(Vue, React和Angular)都是使用的Webpack進行打包, 就目前的使用來看, 通過各種loader和plugins, 幾乎webpack能夠滿足所有的項目需求. 在前端架構中, 由于項目工程化的要求, 使用gulp和webpack這類的自動化工具進行項目的構建是必須的.
(四)測試
測試是項目把關的最后一個環節, 經過了測試員這關才能把項目進行驗收上線. 現在國內的網絡公司由于項目工期的要求, 對于測試這一塊, 大部分的做法還是雇傭能力水平一般的測試人員, 通過重復點擊運行項目流程的方式進行測試, 對于測試工具的使用較少. 目前其實已經有了一批成熟的js測試工具, 例如Jasmine, Karma, Mocha, NightWatch.當你開始為應用程序規劃測試時, 請記住以下幾條建議:
- 測試用例應該在建站的同時, 甚至在建站之前就開始編寫
- 測試代碼是真實的代碼, 應該一起或立即提交到系統代碼庫中
- 必須在所有的測試用例通過后, 才能把代碼合并到主干中
- 在主干上運行測試工具, 結果應該都為通過才能上線
前端自動化測試的細節將在下一篇的文章中做詳細的探討, 這里我們只是強調測試在整個項目流程的必要性.
(五)上線
在測試通過之后, 一個項目的最后流程就是上線了. 上線時采用JenKins這類的持續集成工具進行代碼部署是一個優秀的架構所必須的, 持續集成工具能夠在代碼發布到服務器前, 先對代碼進行一些處理, 這意味著我們可以在Git上忽略那編譯后的資源. 以Vue的項目舉例, 我們上線前只需要將在dev上測試通過的代碼merge到master分支上, 在上傳到遠程Git倉庫中. 在使用Jenkis進行部署上線就行, 一旦配置過上線前的處理流程, Jenkins就能自動幫我執行npm run build
的操作并將build
好的dist文件夾自動部署到服務器上.
友情鏈接
- 前端進階之路: 前端架構設計(1)-代碼核心
參考資料
- 前端進階之路: 如何高質量完成產品需求
- 產品原型的重要性
- 原型設計是什么, 該怎么使用它?
- 改進我的前端工作流