微前端——前端開發新體驗

團隊在去年使用微前端架構重新構建了一個門戶站點。透過引入微前端架構,解決了單體架構下、多團隊協作所產生的相互影響,相互依賴的問題,使得團隊更大程度的獲得了自治權。

本文選取業務模型,技術實踐,服務資產管理三個視角,透過分析專案迭代開發存在的問題,嘗試說明原有單體架構下的痛點,以及引入微前端如何解決痛點問題,從而改善各個團隊工作方式。最後,我們將總結分享在對門戶站點進行微前端改造過程中所汲取到的經驗和教訓。

背景

早前,團隊構建了一個一站式門戶站點,需要整合多個系統,包括:訂單系統,偏好推薦系統,產品系統等;歷時半年,選擇React & Redux作為前端開發框架和工具,使用Kotlin作為BFF開發語言,以單體應用的形式,團隊將該門戶站點發布到AWS中投入使用。此後的幾個月,隨著交付更迭,隨著越來越多團隊加入,我們遇到了一些團隊協作的問題。

業務模型 - 交付計劃相互影響和高額的溝通成本

以訂單,偏好推薦和產品為例,下圖描述了該站點上各個團隊的業務模型:

微前端——前端開發新體驗

由圖中灰框可知,專案分為前後端兩部分:前端和相應的BFF,多個團隊在相同的程式碼倉庫中共享程式碼,共享環境,協同開發。這種模型存在的問題是:當某團隊的一次更新影響範圍較廣時,很可能會影響到其他團隊開發計劃、釋出計劃。

對於PM / BA而言,多團隊協作專案中不必要的耦合會使交付變得不安全且不可預測。一個功能的誕生,從探索,評估,計劃,到最終交付,需要跨團隊大量溝通,包括業務之間的相互影響,技術決策,交付計劃。為了使所有團隊儘可能按計劃交付,我們不得不增加協調成本並提前計劃。不幸的是,通常問題不會在這一過程開始時發生,而是直到過程後期才被發現。它就像一枚複雜的炸彈,使估算無效,降低交付的穩定性和可預測性。

技術實踐 - 強制遵循相同的實踐和技術棧

下圖展示技術實踐具體情況:

微前端——前端開發新體驗

透過上圖我們看出,多個貢獻者團隊以及一個管理團隊共享程式碼庫,共享流水線,共享環境。而作為一個交付團隊,因為共享,不得不接受不熟悉的技術棧;被迫接受更多流水線執行時間以透過所有團隊的測試用例;因為業務關聯而被迫相互學習業務知識。而相互獨立的程式碼庫、熟悉的技術棧,輕量便捷的規範準則、合理而高效的流程,才是一個交付團隊持續不斷追求的理想狀態。

服務資產管理 - 框架或依賴升級帶來的影響

微前端——前端開發新體驗

從服務、資產的角度來講,受限於技術架構與實踐,多個團隊共用相同的工件與產品環境。為了能夠讓每一個團隊都能正常工作,大家被迫妥協、接受滿足所有團隊的管理流程。而實際上各個團隊產品迭代釋出都是對工件和生產環境的更新,這種更新需要整體迴歸測試的保證。甚至線上產品事故支援時,我們需要解決當站點產生的事故,如何將錯誤準確導向特定的開發團隊的問題。

所有團隊經過多次取捨與妥協後,失去了應有的自治權。一個重前端的專案中,整體式架構、多團隊協作開發的模式為我們帶來的思考是:業務如何做到獨立交付?如何做到自主技術決策?如何保障團隊對服務、產品的絕對控制權?微前端架構很好的回答了以上三個問題。

微前端架構及其價值

業務交付上,微前端作為DDD在前端的擴充套件,按照與後端領域相同的拆分方法,可以將前端拆分成獨立的Micro App。各個Micro App僅與對應的BFF進行通訊,BFF只聚合下游服務,從下游服務獲取資料,從而讓Micro App在業務層面實現完全拆分。每個Micro App是一個完整的業務領域,擁有獨立業務價值,業務變化完全由各個團隊自己負責。業務變化幾乎不會影響整個站點。

微前端——前端開發新體驗

同時,作為交付團隊,團隊可以專注於自己的業務領域,建立並維護邊界清晰的前端模組,最大程度地降低各個領域之間耦合關係。這種清晰的業務邊界,極低的耦合關係迎合了PM/BA的訴求:業務模組足夠獨立,交付更加安全且可預測,交付計劃被影響的機率降低。

在開發模式方面,給與團隊足夠的自主決策權。團隊可以自己決定程式碼儲存在哪裡,靈活選擇適合程式語言的程式設計規範,流水線組成,CD實踐等,如下圖所示:

微前端——前端開發新體驗

透過分離最終交付工件,團隊獲得了獨立的程式碼庫,熟悉的技術棧,合適的規範,輕量靈活的流水線及高效的釋出流程。

在服務資產管理方面,不同工件對應於獨立的產品環境,達到各個Micro App之間產品環境隔離的目的。這樣,對整個產品環境的迴歸測試變成了對某個Micro App的迴歸測試。各個團隊只需要響應自己維護產品的線上事故,對自己負責的Micro App制定On-Call support輪值計劃。

微前端——前端開發新體驗

有關SingleSPA的更多資訊,請參考這裡。此處僅以偏好推薦系統為例,展示微前端體系結構中包含的所有重要元件。 使用者透過root container訪問偏好推薦系統。 一旦root container收到訪問偏好推薦系統的請求,它將透過import-map找到其最新的下載地址。

從圖中可以看出,偏好推薦提醒作為Micro App在環境中幾乎是完全隔離的,偏好推薦團隊可以根據需要輕鬆地對其進行更新。

總結起來,微前端改變了多團隊的協作方式:

團隊工作在基於業務領域劃分的端到端專案,這使我們的交付更加穩定和可預測:團隊可以更加關注領域內業務價值的實現以及對專案的迭代更新。 業務迭代更新取決於團隊自身。

能夠充分進行自主技術決策,維護小而聚合的程式碼庫及相關基礎設施:團隊擁有完全自主的決定權,定製更靈活地,符合團隊自身和工作內容的技術實踐。

獨立進行測試與部署:更新、升級的影響範圍被控制在每一個Micro App中,各團隊只需負責開發、維護自己的Micro App即可。

此外,而上文提到的import-map元件,本質上是一種動態載入JS的機制實現,這種機制為吸引更多人、更多團隊、乃至第三方成為所構建平臺的貢獻者提供了可能。

實踐經驗與教訓

微前端架構給團隊帶來了極大的自治權,團隊在領域內、在自己維護的Micro App中獲得了極大的自主權,可以更加靈活的選擇更合適的方式解決實際的業務問題。在認清這些紅利外,微前端並不能解決所有問題,這種架構實踐並非沒有代價,主要表現在引入的效能問題,要求較高的DevOps以及管理複雜度。對此我們需要引入其他技術手段克服:

效能:引入微前端框架,瀏覽器載入頁面時需要最先載入微前端框架程式碼,而後載入各個元件和MFA,這無疑加重了瀏覽器的載入負擔。為了減少頁面載入時間,一方面需要藉助工件最小化,Tree shaking,以及在Cloudfront & 瀏覽器等層面上的快取等手段加快每一個JS指令碼檔案的載入速度;另一方面需要在確保功能完整的情況下,儘可能提高JS指令碼並行載入能力。

DevOps:微前端架構實踐對團隊CD能力也有要求。可以說與CD實踐相輔相成。透過流水線保持Micro App引用最新,這需要較高的自動化要求和高度Infrastructure as Code實踐。而為了高度的自動化,也需要足夠有信心的測試覆蓋,如此才能保持業務的持續交付,持續整合。

管理複雜度:多個不同的Micro App元件同時載入,透過命名規範可以解決潛在的CSS/JS衝突問題;由於UI在前端被分割成了一個個邊界清晰的Micro App,我們需要一定的設計規範,保持跨Micro App的設計一致性,如統一的配色樣式,風格接近的操作方式,行為一致的錯誤處理等。我們相信,再追求高度自治的情況下,並不能以犧牲流暢統一的使用者體驗為前提。

文/Thoughtworks李胤龍

原文連結:https://insights.thoughtworks.cn/micro-frontends-experience/

更多精彩洞見,請關注微信公眾號:Thoughtworks洞見