原文javascript
考慮到關於微前端的第一篇文章的大量反饋,以及咱們在 DAZN 採用的方式收到的問題,我決定分享更多有關這個話題的內容。html
在這篇文章中,我將一一介紹微前端架構各類可能的實現。前端
儘管微前端是咱們前端應用的新模型,但許多公司都已經試圖接受它們背後的原則,而且已經締造了多種實現方式,來解決它們的前端和組織上的挑戰。java
在開始考慮咱們如何設計咱們的實現以前,我認爲值得一提的有一些方式,這不是一個詳盡的列表,但有趣的是,它們能夠被用來了解可用的不一樣可能性:git
在桌面端中使用微前端,利用 iframe 將同一視圖的不一樣部分拼接在一塊兒。github
iframe 之間的通訊是經過事件總線進行的,該事件總線很好地分離了應用的不一樣部分,容許它們在不知道誰將要收聽消息或事件的狀況下進行通訊。 此外,這種方法能夠節省大量的時間來管理應用內存,由於每次咱們更改 iframe 位置時,全部對象均可以自動進行垃圾回收。web
決定採用不一樣方式實施微前端,他們使用的是 Edge Side Includes(ESI)與 Client Side Includes(CSI)混合,我不想在這個技術上贅述,由於它在Gustaf的帖子中被普遍說起,不過,它絕對是另外一種動態生成咱們頁面內容,並在 CDN 級別或客戶端緩存結果的機會,這取決於咱們想採起的方法。後端
它是 Skyscanner、OpenTable 等幾家公司使用的有意思的框架。瀏覽器
OpenComponents 是一個以自我爲中心(opinionated)的框架,它利用端到端組件(前端+後端)的概念,把這些組件提交給一個寄存器,而後用來組合一個應用。緩存
還有,在這種狀況下,咱們能夠在 OpenComponents 項目網站上找到更多的信息。
在這 3 個實現之間,咱們能夠找到類似的地方,但其中的一些差別,會被中大型規模的組織用來建立獨立和技術不可知的微前端。這方面值得一提的是 Zalando 或 BuzzFeed 也是做爲這個思想流派中的另外一種貢獻者。
若是咱們想總結一下到目前爲止討論的實現,咱們能夠列出 3 種不一樣的方法:
。使用iframes + 事件總線 。使用 ESI 結合(或不結合)CSI 。使用 OpenComponents 或相似的運行時/編譯時模板系統
正如我在本文開頭所提到的,還有另外一個實現要討論:DAZN 採用的方法。
DAZN 是一種 OTT 服務,可在多個國家/地區提供實時和點播內容。咱們的應用不只能夠在網絡和移動設備上使用,還能夠在智能電視,機頂盒和控制檯上使用,這一點很是重要,由於咱們常常遇到獨特的挑戰,咱們須要開箱即用地來解決它們。
一般,當咱們開始一個微前端項目時,咱們應該問本身幾個問題,並基於與咱們的決策面臨的相關挑戰的答案,例如:
讓咱們嘗試回答全部的這些問題,以便理解咱們採用的方法......
咱們想在同一個視圖中使用多個微前端嗎?
不,咱們但願每次加載 1 個微前端,這樣咱們就沒有微前端之間的共享依賴關係,每一個微前端都足夠小但不過小,咱們徹底控制最終的結果,它是獨立的技術和良好的封裝。
咱們可使用同一框架的不一樣版本,而不會影響其餘微框架甚至不一樣的技術,從而不會對整個應用產生任何影響。
咱們遵循領域驅動設計(DDD)實踐來切割咱們的子域,並使它們真正獨立地映射產品團隊結構,並在由產品人員+前端開發人員+後端開發人員+功能測試+測試開發組成的大型組織內建立垂直,這對於快速迭代很是有用,在大公司須要時,團隊之間的速度會有所不一樣。
請記住,比你想象的更頻繁,咱們的應用並不是徹底地被用戶使用,例如,當用戶經過身份驗證時,將不會加載登陸/註冊微前端的全部代碼和依賴項,由於咱們只加載通過驗證的區域的微前端。 同時,當用戶未通過身份驗證時,並非 100% 肯定她將完成登陸的流程,併成功訪問應用的通過身份驗證的區域,請檢查你的用戶與你的用戶交互方式的統計信息應用,若是你沒有使用它們,請使用 Google Analytics,Sentry,LogRocket 等工具投入適當的時間來建立正確的可觀察性。 請記住,微前端的目標是幫助實現加載僅僅是用戶須要的 而不是更多。
咱們如何在頁面之間切換路由?如何在微前端之間共享數據?
咱們能夠經過多種方式在後端,邊緣或客戶端實現這一點。咱們選擇客戶端建立一個名爲 Bootstrap 的 協調器(orchestrator),它有 4 個主要目標:
咱們如何生成微觀前端?運行時或編譯時間?
咱們喜歡咱們用的人工製品的結果很是可預測,咱們但願它們像 SPA 同樣高度安全,所以咱們沒有采起在運行時建立任何東西的路徑,但咱們比較喜歡在編譯時生成微前端,把它們存儲在 AWS S3 上,並經過 Cloudfront CDN 提供服務。 經過這種方式,咱們沒必要擔憂在咱們爲應用提供服務時擴展咱們的基礎架構的問題或發生不可預測的邊緣狀況,咱們能夠在部署生產環境以前運行端到端測試和性能測試,從而在上線以前對咱們部署的內容更有信心。
在咱們的案例中,咱們決定將應用拆分爲多個子域,以便提早研究用戶如何與咱們的 Web 應用進行交互。對於綠地(green-field)項目,我建議深刻了解你的用戶如何與你的 UX 和產品團隊一塊兒與應用進行交互,並遵循領域驅動設計用於定義子域及其相關的邊界上下文。 對於 DAZN 應用,幾乎每一個子域在技術上都被轉換爲單頁應用,但也有一些例外,例如,因爲該子域的普遍範圍,視頻播放器是一個組件,而後這些組件被導入到微前端內部和任何其餘庫同樣。
微前端由引導程序加載和協調,引導程序是嵌入在主 HTML 頁面中的簡單的 vanilla javascript 應用,它根據深層連接(deep-link)來請求加載不一樣的微前端,用戶狀態或任意請求都來自加載的微前端。
這就是咱們的架構的樣子:
引導程序在咱們的應用的生命週期中始終可用,它負責加載咱們的微前端,並在設備和微前端之間暴露一層微小的抽象。
當你的目標是多個設備而不只僅是瀏覽器時,也就是咱們在許多智能電視,機頂盒和控制檯上均可以使用咱們的應用時,這個細節變得更加相關,它們一般都有不一樣的要求和I/O API ,他們被順延封裝在引導程序級別。
經過這種方式,咱們能夠在多個設備中運行微前端而無需更改一行代碼,由於引導程序正在抽象運行微前端的平臺。
若是咱們想總結應用在瀏覽器中的加載方式,咱們能夠說:
請記住,每一個微前端都是獨立的,所以咱們不會在微前端之間共享組件或邏輯。
若是你認爲這是浪費時間和精力,你就沒法想象每一個團隊在這個決策中得到了多少獨立性。
代碼重複並不老是一種糟糕的作法,正如咱們過去所瞭解的那樣,一般跨團隊依賴和代碼抽象風險比建立相同組件的 3 到 4 倍更危險和繁瑣。
咱們注意到,花費適當的時間來分析用戶流並識別子域能夠減小重複次數。
此外,咱們注意到使用微前端的話,因爲最初分析項目並建立有意義的子域,所以跨團隊的依賴關係並不像其餘項目那樣常常發生。
若是在你的狀況下,它是絕對必須重用的組件,有一種方法可使用 Web 組件來減輕重複,以標準化組件代碼,使用這種技術,它能夠與任何框架結合使用,但這個討論應該在另外一篇帖子裏😉。
當咱們開始邁向微前端時,對我來講很是清楚的是必須考慮開發團隊的將來,而不只僅是解決技術問題。
藉助微前端,咱們可以在不影響交付速度的狀況下提供我所尋求的獨立性,每一個團隊都擁有端到端的特定域,保證了添加新功能,修復錯誤或添加改進的簡單方法,沒有冒着對咱們的多個開發中心傳播的其餘應用或依賴關係產生影響的風險。
與新開發人員加入公司以及在個人會談或在線研討會期間屢次分享這些信息後,我知道你可能會有大量關於引導程序的問題,它如何加載微前端,如何共享數據等等。
我將在下一篇文章中回答全部這些問題,這些問題將集中在引導程序上,因此請跟隨我,不要錯過微前端世界中的深潛。
若是你對微型前端有任何好奇或疑問,請隨時與我聯繫,我老是熱衷於儘量多地幫助社區😁!