簡介: 微前端帶來明顯好處的同時,也面臨著痛點。對於已有站點,如何在老的技術棧基礎上接入一個微前端?需要哪些通用功能?如何解決外掛機制?本文分享一種微前端的接入方案和實現細則。
一 、前言微前端,這個概念已經在國內不止一次的登上各大熱門話題,它所解決的問題也很明顯,這幾個微前端所提到的痛點在我們團隊所維護的專案中也是非常凸顯。
"微前端就是...xx 框架,xx 技術"
這種話就有點把這種傑出的思路說的侷限了,我只能認為他是外行人,來蹭這個詞的熱度。
在我所負責的專案和團隊中,已經有非常大的存量技術棧和頁面已經在線上執行,任何迭代升級都必須要保證小心翼翼,萬無一失。
可以說,從一定程度來講,微前端所帶來的這些好處是從使用者體驗和技術維護方面的,對業務的價值並不能量化體現,落地這項技術秉著既要也要還要的指導方針。
我們對存量技術棧一定需要保持敬畏,隔離,影響範圍可控的幾個基本要素,然後再考慮落地實施微前端方案。
所以,在這個基本要素和指導方針下,要落地這項新的技術,一定要充分了解當前改造站點所存在的技術方案、佔比以及當前成熟的微前端框架已提供的能力差異,切勿生搬硬套。
二 、背景我所在團隊維護的專案都是些 PC 操作後臺(Workstation),這些工作臺會存在不同的國家,不同時區,不同合作方等等問題。
如果需要開發一個新的頁面需求,很可能投入進來的開發人員都來自不同團隊,此時我們要在完成現有需求的同時還需要保證多個管理頁面的風格統一,設計規範統一,元件統一,互動行為統一這非常困難。
當該業務需要遷移到另外一個工作臺時,雖然需要保持邏輯一致,但導航欄、主題等卻不同。
當前存量的方案都是採用 Java 直接進行 Template 渲染出 HTML,經過前面幾代前輩的迭代,不同系統中已經存在幾種不同技術棧產出的頁面。
雖然都是 React 來實現的,但是前輩們都非常能折騰,沒有一個是按照常規 React 元件形式開發出來的。
比如:
大部分頁面是透過一份 JSON 配置,消費元件生成的頁面。部分頁面是透過另外一個團隊定義的 JSON 配置消費元件生成的,與上面 JSON 完全不一樣。還有一部分頁面,是透過一套頁面釋出平臺提供的 JS Bundle 加載出來的。面對這樣的技術背景下,除了微笑的喊 MMP,含淚說著自己聽不懂的話(存在即合理,不難要你幹嘛?),還得接地氣地出這樣一個落地方案。
三 、方案 & 流程圖首先,需要明確的分析出站點所有頁面,所需要載入的通用特性:
上述是精簡過後的一些通用功能特性,這裡簡單做下介紹:
Layout Loader:用於載入不同工作臺的導航DADA Loader:用於載入 JSON 配置的頁面Source Code Loader:用於載入 JS BundleMicro Loader:用於處理微前端載入Log Report:用於日誌埋點Time Zone:用於切換時區i18n:用於切換多語言Guider:用於統一管控使用者引導除此以外可能還會存在以下這些頁面擴充套件能力:
安全監控流量管控彈窗管控問卷調查答疑機器人粗略統一歸類後來看,頁面的大體載入流程應該是這樣:
四、 實現細則基於上述一個載入思路,首先需要做的是頁面載入路徑收口,需要保證所有頁面的載入入口是在一個統一的 Loader 下,然後才可以較為系統的處理所有頁面的載入生命週期。
在收斂的同時,同樣需要保持開放,對核心載入路徑要保持外掛化開放,隨時支援不同的擴充套件能力,渲染技術棧接入。
1 、外掛機制
所以,在主路徑上,透過 Loader 載入配置進行處理,這份配置在主路徑中提供上下文,然後交由外掛進行消費,如圖所示:
舉個例子,拿一個獨立的 JS Bundle 型別的子應用來說:
<div id="root"></div><script src="https://cdn.address/schema-resolver/index.js"></script><script src="https://cdn.address/schema-resolver/plugin/layout.js"></script><script src="https://cdn.address/schema-resolver/plugin/source-code.js"></script><script src="https://cdn.address/schema-resolver/plugin/micro-loader.js"></script><script src="https://cdn.address/schema-resolver/plugin/i18n.js"></script><script> SchemaResolver.render( { micro: true, host: "dev.address", hfType: "layout1", externals: ["//{HOST}/theme1/index.css"], // host is cdn prefix, the resource maybe in different env & country resource: { js: "/index.js", css: "/index.css", }, }, { container: document.querySelector("#root") } );</script>
透過上述的 Plugin 引入,即可開啟和消費不同的配置。
這裡引入了 Layout Plugin,該外掛會消費 hfType 欄位然後去載入對於的 Layout 資源提供 Container 交給下一個環節。
按照配置,當前頁面開啟了微前端,那麼 Micro Loader 將會消費提供下來的 Container,然後建立沙箱(這裡基於 qiankun),再提供 Container 出來。
最後交由 SourceCode Plugin 進行 Bundle 載入執行和渲染。如果這裡是另外一種渲染協議或者技術棧,則可以根據不同配置交由不同外掛消費 Container。
這個過程中,每個環節的外掛是不依賴的,可插拔的。
比如:
如果不載入 Layout Plugin 將不會消費 hfType 欄位,也就不會將 Layout 外掛邏輯注入到getContainer方法中,那麼將直接得到由最外層下穿的 Container 進行渲染,也就不會有選單相關透出。
如果不載入 Micro Plugin 同樣不會有微前端的邏輯注入,也就不會建立沙箱,那麼頁面渲染流程將會按照常規模式繼續執行。
2 、安全遷移
對於我所在團隊負責的專案來說,萬萬做不得一刀切的方案,所以針對現有存量頁面,需要完整分析當前存量技術棧:
針對上述存量頁面來說,需要從左到右分批進行頁面級別控制上線部署,對於左側部分頁面甚至需要做些專案改造後才可部署接入上線。
這類遷移測試需要處理出一套自動化 e2e 測試流程,透過分批遷移同時梳理出 微前端登錄檔 。
有了這兩項流程保證及範圍控制,當前方案所上線內容完全可控,剩下要處理的大部分就是較為重複的體力活了,覆蓋率也可量化。
3、 微前端形態
按照上述方案遷移,那麼預期的微前端形態將會是:
每個開啟微前端的頁面都可成為主應用。微前端是外掛可選項,如果因為微前端導致的業務異常可隨時關閉。同為微前端的頁面路由相互之間切換可實現區域性重新整理形態,而跳轉至非微前端登錄檔中的頁面則會直接頁面跳轉。隨著微前端頁面覆蓋率提高,區域性重新整理的覆蓋率也會逐漸提高。可透過不同擴充套件外掛,載入不同技術棧型別的存量頁面,轉換為對應子應用。在 SchemaResolver 中的註冊和呼叫路徑如下:
五 、總結透過技術看本質,微前端所代表的傑出思維,才是真正解決具體問題關鍵所在,只有解決了具體的業務問題,這項技術才有價值轉換。
不要為了微前端做微前端,不要為了小程式做小程式。
當前,透過 SchemaResolver,可以針對不同角色提供不同的開放能力:
針對平臺管理員,提供外掛能力開放全域性擴充套件能力。針對頁面開發者,提供標準化接入方案路徑,提供多種技術棧接入能力,並無感知提供微前端,多語言,埋點,選單,主題載入等能力。解耦了不同系統公共能力,同時,這種方式可以讓頁面開發者快速將具體業務邏輯遷移到其他平臺。針對第三方接入者,不需要關心瞭解系統選單、主題接入方式,提供統一的接入口徑,透過微前端隔離技術棧、隔離子應用樣式。最後透過統一的頁面系統管控,輕鬆入住對應平臺,同時可以全域性看到站點頁面情況。作者:開發者小助手_LS