網上開店系統Wix如何將微前端提升到一個新的水平? - Shaha

banq發表於2021-08-13

微前端的概念已經存在很長一段時間了。自 2013 年左右以來,我們一直在 Wix 中使用這種架構,甚至早在它被賦予這個名字之前。這也是我們在 2016 年從 AngularJS 逐步遷移到 React 的關鍵因素。多年來,我們一直在發展它並收集大量經驗。在本文中,我想分享我們為發展開發大規模微前端的概念所做的一些事情(在撰寫本文時,我們有 700 名開發人員致力於此架構)。
 

微前端簡介
有 很多關於微前端的文章,本文試圖關注更高階的主題,所以我會盡量使介紹非常簡短。當一個團隊變得非常大時,許多人開始開發一個單體應用程式變得非常困難:

  • 程式碼庫變得非常大,難以維護並且充滿了不必要的複雜性。
  • 構建變得很長,並且涉及許多移動部件,大多數開發人員不知道在出現問題時如何處理。
  • 部署包含太多更改,這意味著完全不相關的更改可能會阻止人們部署或強制回滾版本。
  • 名單還在繼續。Monoliths 在大團隊中很難維護,如果你在這裡,我想你知道這一點。

這就是為什麼在大團隊中,嘗試將應用程式分解為更小的獨立事物是一個好主意,這些事物可以在單獨的專案中開發,單獨構建和彼此分開部署。我一直強調,這對於大型團隊來說是一種明智的方式。如果你有一個小團隊,不要這樣做,它只會讓你的生活更艱難。在 Wix 中,只有當我們有大約 100 名開發人員在開發前端應用程式時,我們才開始使用這種方法。
我見過的演示這種方法的最簡單的例子是這樣的:

<html>
    <head>
        <script src="https://shipping.example.com/shipping-service.js"></script>
        <script src="https://profile.example.com/profile-service.js"></script>
        <script src="https://billing.example.com/billing-service.js"></script>
        <title>Parent Application</title>
    </head>
    <body>
        <shipping-service />
        <profile-service />
        <billing-service />
    </body>
</html>

所以,我們這裡有三個獨立的包。每個都可以單獨開發、構建和部署,每個都註冊一個自定義元素,父應用程式最終可以呈現該元素。不要誤會我的意思,您不必使用自定義元素來擁有微前端架構;這些包可以將 React 元件註冊到父應用程式使用的某個全域性 Map 以便在渲染時引用它們(這實際上是我們在 Wix 所做的),但是自定義元素示例是一種很酷的方式來展示它而無需去進入這些細節。
 

Wix 的微前端
我將深入探討我們多年來構建的內部架構和工具的許多細節,所以我想花點時間快速瞭解一下 Wix 平臺,別擔心你不必瞭解很多關於 Wix 的資訊。
Wix 是一個平臺,人們可以使用 WYSIWYG 編輯器為其業務建立站點,並使用各種業務管理工具管理業務。這意味著,例如,企業主可以建立一個帶有線上商店的站點,他們的客戶可以在其中將商品新增到購物車、檢視購物車、結帳、檢視訂單狀態等,所有這些都可以透過完全可定製的站點進行。另一方面,企業主可以在 Wix 上管理商店,這意味著他們有管理頁面,可以在其中編輯目錄、檢視訂單和分析、瀏覽客戶和管理庫存;所有這些都在一個呼叫業務管理的大應用程式中。
但它並不止於此,網站還可以有部落格、論壇和註冊/登入螢幕,或者它們可以是可以訂購食物或預訂餐桌的餐廳網站,或者它們可以是會議或音樂會的網站人們可以在那裡購買門票並選擇他們想坐的地方,甚至可以從網站內線上觀看。在業務管理方面,企業主還可以向客戶傳送時事通訊、管理其業務的線上活動、建立自動化(例如,在交付後 5 天向客戶傳送反饋電子郵件),甚至與當前在其網站上的人聊天。
你得到了圖片。網站和業務管理都有大量功能。這就是為什麼我們決定呈現所有站點的檢視器和業務管理都將是微前端主機。在本文中,我們將重點介紹這兩個平臺及其不同的需求。
老實說,我們實際上在 Wix 中還有兩個微前端主機,它們是編輯器(所有站點都在其中建立)和我們的移動應用程式(我所知道的世界上唯一的微前端 React Native 應用程式))。但是,每一個都值得擁有自己的文章,因此我們不會在本文中觸及它們。

  • 簡而言之,在業務管理器中執行的微前端可以是託管在側邊欄旁邊的完整頁面體驗,或者新增到頂部欄中的小部件,或者託管在不同微前端內的小部件。
  • 簡而言之,檢視器將編輯器建立的大 json 轉換為動態 React 元件樹,其中每個元件都取自擁有它的微前端,並傳遞設定和設計引數,這些設定和設計引數也儲存在那個json。


 

可插拔微前端
讓我們討論我們在開發檢視器和業務管理器時遇到的第一個挑戰。與許多應用程式的功能是預先確定的不同,我們的應用程式根據上下文載入了完全不同的功能集:

  • 每個企業都安裝了不同的擴充套件程式,每個擴充套件程式都可以在業務管理器側邊欄和路由器中註冊一個頁面,以便使用者可以導航到它。
  • 每個擴充套件還可以註冊其他型別的業務元件,例如顯示您在螢幕截圖業務管理器 (3) 中看到的特定聯絡人資訊的選項卡。
  • 站點中的每個頁面都有使用者在編輯頁面時放置的不同小部件,並且每個小部件在 DOM 樹中的位置可能不同,具體取決於使用者附加小部件的父級。

這些不是 Wix 的特殊要求。這些是可插拔系統非常經典的特徵,這正是我們為解決這些問題而建立的。此外,微前端是可插拔系統的經典解決方案,是我們解決方案的重要組成部分。讓我們討論可插拔微前端的構建塊是什麼。
首先,我們需要有一個地方來儲存有關現有擴充套件、頁面和小部件的所有資訊。例如,我們需要知道電子商務 擴充套件包括應該出現在業務管理器中的產品管理器和訂單管理器頁面,並且每個頁面在業務管理器中都有一個專用的側邊欄條目和路由。
另外,電子商務擴充套件包括訂單,其應顯示在與一些標籤標題接觸檢視接觸標籤。
最後,電子商務 擴充套件包括產品庫、產品和購物車使用者可以在網站的某些頁面上放置的小部件。
那麼我們將所有這些資訊儲存在哪裡呢?我們有一項稱為開發中心的服務,Wix 中的每個開發人員都可以在其中定義一個新的擴充套件。一個擴充套件可以有多個元件,每個這樣的元件可以是不同的型別和與此型別相關的資料。因此,如果我們以電子商務擴充套件程式為例,它包括以下元件:
  1. 產品管理。型別:業務管理頁面。資料:捆綁 URL、側邊欄標籤、路由路徑。
  2. 訂單管理。型別:業務管理頁面。資料:捆綁 URL、側邊欄標籤、路由路徑。
  3. 訂單選項卡。型別:聯絡人選項卡。資料:捆綁 URL、標籤標題
  4. 產品畫廊小部件。型別:檢視器小部件。Data : Bundle URL, 一堆編輯器相關的資料我們就不講了。
  5. 產品小部件。型別:檢視器小部件。Data : Bundle URL, 一堆編輯器相關的資料我們就不講了。
  6. 購物車小部件。型別:檢視器小部件。Data : Bundle URL, 一堆編輯器相關的資料我們就不講了。

所以現在業務管理器渲染的時候,會經過如下流程:
  1. 檢查此站點中安裝了哪些擴充套件程式(我們有一項服務,可以記住每個站點中安裝了哪些擴充套件程式,我們有一個應用程式市場,使用者安裝擴充套件程式,應用程式市場的所有後設資料也儲存在開發中心,但我們不會深入討論)。
  2. 對於已安裝的擴充套件,從業務管理器頁面型別的開發中心獲取所有元件的列表。
  3. 根據元件資料將所有連結動態新增到帶有正確路由的側邊欄。
  4. 使用來自元件資料的路由動態配置 React Router,以便當使用者導航到頁面時,我們將動態匯入可以呈現該頁面的正確微前端元件的bundle url。

當業務管理器中的聯絡人管理器頁面呈現時,會發生完全相同的過程,唯一的區別是它將查詢型別為contact tabs 的元件。相反,它將根據元件資料將選項卡標題動態新增到選項卡選擇器,類似於業務管理器主機在側邊欄中所做的操作。理論上,如果我們願意,聯絡人選項卡的元件資料甚至可以包含一個路由,並且聯絡人頁面也可以在主機的 React 路由器中配置一個巢狀路由。
檢視器經歷了類似的過程,但有一些細微的差別:
  1. 檢查我們將要呈現的頁面結構中需要哪些小部件(我們有一項提供有關頁面結構資訊的服務)。
  2. 對於那些小部件,從開發中心獲取元件資料。
  3. 動態匯入頁面上所有小部件的bundle url,並根據頁面結構呈現動態的React樹。
  4. 在站點中的每個頁面導航中重複該過程(請注意,在 Wix 中,站點的第一個導航是執行 SSR,站點內部的後續導航發生在客戶端(如 SPA)中,因此該過程可以在客戶端和伺服器)。

最後,我們可以定義一個通用模式:一個可插拔的微前端主機需要找出它需要渲染的東西的bundle url是什麼,它需要用安裝的東西動態渲染它的UI,它需要在合適的時間下載正確的包時動態匯入正確的包。除非確實有意義,否則不要急切地下載包非常重要,並且儘可能使用伺服器端快取最佳化這些流非常重要,否則效能會很快成為此類應用程式的瓶頸。
 

整合微前端
到目前為止,我們主要討論了微前端提供由主機應用程式或其他微前端呈現的元件的情況。這是透過每個微前端在全域性對映中註冊其元件來完成的,該對映可用於主機和其他微前端,在這些微前端中,它們透過元件型別呼叫查詢元件,如開發中心所述,以及它們的元件資料,可以用於在側邊欄中呈現連結、配置路由器等。
但是,如果某個微前端想要呼叫不同微前端中的某些功能怎麼辦?
使用模組登錄檔.
,,,
 

第三方微前端
Wix 是一個開放平臺,這意味著我們希望能夠為不在 Wix 工作的外部開發人員建立業務管理器頁面和檢視器小部件。也就是說,這仍然意味著我們需要牢記使用者的安全性,這意味著外部微前端需要以“老派方式”工作,這意味著它們在 iframe 中被沙箱化。它的工作方式是我們有一個特殊的微前端業務管理器頁面,它實際上可以託管外部開發頁面的 iframe,並使用釋出訊息將所有業務管理器的 API 橋接到它。

結論
很明顯,為了解決微前端引入的許多問題,我們做了很多工作,因為我們相信這個解決方案為處理大規模問題的團隊提供了大量的速度和獨立性。我們希望有一天能夠公開發布其中一些工具,並相信很多人會發現它們很有用。我們建立的許多解決方案對於單體應用也非常有用,但毫無疑問,微前端是有成本的。
在過去的 2 年裡,我們投入了大量資金來建立一個我們稱之為 Falcon 的構建系統,我們相信它可以用於智慧地構建非常大的單一儲存庫(是的,我們已經研究了 Bazel,但目前我們正在使用內部的出於本文討論範圍之外的原因的解決方案)。這對我們來說非常重要,因為即使在微前端世界中,我們也希望能夠為每個擴充套件提供單一儲存庫,但它也將允許我們嘗試替代解決方案,將一個巨大的東西作為一個整體構建和部署.

我並不是說我們放棄了微前端,我認為不要完全迷戀一種解決方案並嘗試看看其他方法是否可行,這一點非常重要。
我從整篇文章中最重要的收穫是,解決如此眾多的基礎設施挑戰是一次令人難以置信的經歷,而這些挑戰只有生活在這些技術前沿的工程組織才能解決,我相信我們未來還會面臨更多此類挑戰。

 

相關文章