導讀:本文由梯度科技前端研發(fā)部高級開發(fā)工程師賀信撰寫,主要介紹如何基于前沿開源的前端技術(shù)方案實現(xiàn)微前端在大數(shù)據(jù)平臺中的應用落地,并對所取得的應用效果進行剖析。主要包括以下幾個方面:
案例背景
微前端解決方案對比和決策
實例應用剖析
無界框架源碼與原理
實踐總結(jié)
一、案例背景
根據(jù)公司產(chǎn)品某項需求,需要引入一個新應用作為一個獨立模塊集成進已有大型平臺。公司本身產(chǎn)品的前端技術(shù)棧與待引入的新應用技術(shù)棧不同,分別采用的是vue和react,使用的UI框架也截然不同。新應用可以獨立開發(fā)部署,但為了產(chǎn)品體驗的一致性,需要將新應用嵌入已有業(yè)務中,并通過少量的改造使產(chǎn)品功能融為一體。
1.0階段:采用外鏈跳轉(zhuǎn)的方式,點擊菜單打開新tab頁展示數(shù)據(jù)開發(fā)模塊功能
2.0階段:采用iframe內(nèi)嵌頁面的方式,點擊菜單在當前頁面通過iframe加載url
3.0階段:采用wujie微前端方案進行父子應用改造,組件式加載子應用方便快捷
4.0階段:利用微前端能力實現(xiàn)模塊拆分節(jié)約50%工作量,新增跨模塊功能不再受限于技術(shù)棧
在引入wujie微前端方案后,對大數(shù)據(jù)平臺產(chǎn)生了積極影響:
收益變現(xiàn)
主框架不限制接入應用的技術(shù)棧,微應用具備完全自主權(quán),做到新技術(shù)選型時“技術(shù)棧無關(guān)”。
微應用倉庫獨立,部署完成后主框架刷新時自動完成同步更新,每個微應用之間狀態(tài)隔離,運行時狀態(tài)不共享,獨立運行時。
在面對各種復雜場景時,對已經(jīng)存在的系統(tǒng)做全量的技術(shù)棧升級或重構(gòu)不現(xiàn)實,而微前端是一種非常好的實施漸進式重構(gòu)的手段和策略,能夠做到增量升級。
便捷的alive?;钅J?,可以確保在用戶經(jīng)常切換路由的場景下不丟失編輯狀態(tài),非常適合大數(shù)據(jù)平臺的離線開發(fā)、實時開發(fā)、算法開發(fā)、低代碼等業(yè)務場景。
持續(xù)增值
開啟preloadApp預加載后,能顯著減少白屏時間,結(jié)合?;钅J娇色@得極速的打開體驗。
支持 vite 等 ESM 腳本運行。
提供無感知的iframe降級方案,理論上兼容到IE9,配合插件系統(tǒng)能解決99%的兼容問題。
未來接入其他第三方應用(如BI、3D)將成為剛需,可無負擔的擴展子應用。
二、微前端解決方案對比和決策
可能有人會問目前市面上主流的微前端方案有很多,為什么選擇wujie微前端方案呢?該如何對比和決策?在這之前先來了解一下什么是微前端:
什么是微前端?
微前端是多個團隊通過獨立發(fā)布功能的方式來共同構(gòu)建現(xiàn)代化 web 應用的技術(shù)手段及方法策略,英文名稱叫 micro-frontends。
2016年,首次提出“微前端”的概念,微服務這個被廣泛應用于服務端的技術(shù)范式開始擴展到前端領域。
趨勢:前端越豐富復雜,項目越龐大難以維護。
核心思想:獨立的團隊負責特定的業(yè)務和開發(fā)獨立的功能模塊。
架構(gòu)對比
需要注意的是,這些技術(shù)并不是相互排斥的,實際應用中可能會使用它們的組合來實現(xiàn)應用程序的需求。例如,同構(gòu)應用可以與JAMStack和微前端一起使用,以提高應用程序的性能、可維護性和可擴展性。
實踐經(jīng)驗告訴我們,永遠不要追求最好的架構(gòu),而要追求最不糟糕的架構(gòu)。真實世界里完美的架構(gòu)并不存在,架構(gòu)也沒有對錯之分,只有根據(jù)環(huán)境進行利弊權(quán)衡后的最佳結(jié)果。
微前端決策
在選擇何種方案決策的時候 我們整理了一份決策要素清單:
參考這份清單可以全方位對比每個框架的優(yōu)缺點,幫助選擇最適合的方案。我們選取了目前市面上最流行的幾種方案進行技術(shù)調(diào)研:
阿里開源的 qiankun 方案,基于 single-spa
京東開源的 micro-app 方案,基于 webcomponent + qiankun sandbox
歡聚時代開源的 EMP 方案,基于 webpack5 module federation
字節(jié)跳動開源 Garfish 方案,這是一個集部署、框架、調(diào)試于一體的全套解決方案
騰訊開源的 Wujie 方案,基于 WebComponent 容器 + iframe 沙箱
詳細調(diào)研了各類方案的優(yōu)缺點之后,我們根據(jù)主客觀判斷給出了一個評分表:
最終經(jīng)過多方面的對比和分析,并且在基于產(chǎn)品開發(fā)周期短、使用和改造成本低的實際情況下,決定選擇wujie方案。
三、實例應用剖析
這部分內(nèi)容主要介紹wujie的實施方案和細節(jié),對應wujie使用以及具體開發(fā)過程中解決的問題和最佳實踐。
控制臺展示
從瀏覽器按F12調(diào)出開發(fā)者工具,可以查看大數(shù)據(jù)平臺實施微前端改造后的父子應用前端代碼結(jié)構(gòu):
從元素窗口看到,引入wujie后html里面的實際結(jié)構(gòu),其中wujie-app就是wujie創(chuàng)建的webcomponent自定義組件,可以理解為當前位置之前使用的iframe標簽,現(xiàn)在把標簽替換為了wujie-app,里面的內(nèi)容就是子應用也就是引入的新模塊的內(nèi)容,外面的內(nèi)容就是父應用也就是原來已有的部分。
另外可以看到該自定義組件里面只有dom元素和css樣式內(nèi)容,最關(guān)鍵的js代碼去哪里了呢?繼續(xù)往下翻閱代碼到底部,發(fā)現(xiàn)在最底下多了一個iframe標簽,這個標簽的路徑是當前網(wǎng)頁的路徑,樣式是隱藏的狀態(tài)。
子應用的js是通過一個iframe沙箱的形式加載進來的。在wujie微前端框架的影響下,子應用的js和dom元素以及css樣式是分開的。
wujie使用
wujie的組件式加載方式非常方便快捷,本部門將介紹wujie的vue組件的使用方式。
wujie基于vue2、vue3、React框架的組件封裝了對應的npm包:wujie-vue2、wujie-vue3、wujie-react
父應用安裝并全局引入wujie-vue2。
常規(guī)的使用組件方式和props傳遞參數(shù),與普通組件別無二致。
子應用本身無需安裝任何包,無界對子應用注入了$wujie對象,可以通過多種方式獲取。
也就是說在滿足跨域條件下子應用可以不用做任何改造,可以直接把iframe替換為wujie組件。
需要特別注意一點的是wujie的運行模式,子應用是否開啟了?;钜约笆欠襁M行生命周期的改造會進入完全不同的處理流程。
實際應用方案
以下是我們根據(jù)項目實際情況使用的實施方案和原因理由,需要說明的是在不同公司不同項目是完全可以根據(jù)需求和wujie提供的各種能力來靈活調(diào)整方案的,這里并沒有什么最佳實踐,個人認為只要能很好的滿足需求就都是最佳實踐。
?;钅J?/strong>
選用?;钅J降脑蛑饕幸韵聨讉€方面:
子應用模塊代碼加載量大,?;钅J街恍枰淮渭虞d,避免頻繁切換白屏。
用戶在子應用中使用monaco編輯器編輯內(nèi)容時容易忘記保存,用戶不希望退出當前頁面就丟掉了未保存的輸入內(nèi)容。
子應用模塊里面的底座是用了另外一個高度封裝的Web IDE UI框架,生命周期改造需要修改底座源碼,改造起來需要投入大量的時間成本。
props通信和EventBus方式結(jié)合
我們需要用到子應用模塊里面不止一個頁面,且某幾個頁面要獨立出來,方便后續(xù)做權(quán)限控制。
通過location.query參數(shù)不同判斷展示
通過props傳遞模塊類型和jump方法
通過bus.$on和bus.$emit監(jiān)聽和觸發(fā)子應用的路由變化
兩個wujieVue組件
3.0階段后需要將子應用模塊拆分成兩個模塊,分別有兩個入口,所以用兩個組件來區(qū)分。
父應用有兩個wujieVue組件,每個組件對應多個頁面,props傳不同參數(shù)。
子應用只需要一份代碼,巧妙的通過參數(shù)區(qū)分接口層、業(yè)務邏輯層,并在內(nèi)部發(fā)生路由跳轉(zhuǎn)時通知父應用處理,節(jié)約了50%以上的開發(fā)時間和人力成本。
服務代理
這是父子應用獨立部署兩個服務的情況圖,父子應用之間用nginx做路由跳轉(zhuǎn)和接口代理
頁面結(jié)構(gòu)
在頁面結(jié)構(gòu)示意圖中可以看到綠色部分即原有平臺頁面,菜單導航還在原有代碼里,而新增的藍色部分就是用wujie包裹的部分。
數(shù)據(jù)流程
這是我們的路由和參數(shù)傳遞流程,可以看到我們是用props和EventBus路由同步邏輯的。
為什么我們沒有采用官方提供的路由同步功能,而是手動實現(xiàn)了一套路由同步邏輯呢?主要原因是由于子應用(第三方模塊)不方便進行生命周期改造。
根據(jù)官方文檔介紹,只有無界實例在初次實例化的時候才會從url上讀回路由信息,一旦實例化完成后續(xù)只會單向的將子應用路由同步到主應用url上。但在開啟路由同步后,刷新瀏覽器或者將url分享出去子應用的路由狀態(tài)都不會丟失,會導致子應用永遠也不會刷新。在實際應用過程中我們的多個頁面要通過query參數(shù)來區(qū)分不同頁面,因此必須通過更新路由狀態(tài)來切換不同的頁面。
四、wujie源碼與原理
接下來我們更深入的研究一下wujie的源碼和原理,對如何更好的使用微前端大有裨益。
wujie-core代碼結(jié)構(gòu)
可以看到wujie的核心代碼也十分簡單,總共14個文件,入口在index.ts,可以順著入口一點一點深入源碼進行了解。
wujie-core核心代碼思維導圖
js沙箱和css沙箱鏈接原理和細節(jié)
子應用的實例instance在iframe內(nèi)運行,dom在主應用容器下的webcomponent內(nèi)
無界在底層采用proxy + Object.defineproperty的方式將 js-iframe 中對 dom 操作劫持代理到webcomponent shadowRoot容器中,可以實現(xiàn)兩者的互聯(lián),開發(fā)者無感知也無需關(guān)心。
細節(jié):document的查詢類接口:getElementsByTagName、getElementsByClassName、getElementsByName、getElementById、querySelector、querySelectorAll、head、body全部代理到webcomponent,這樣instance和webcomponent就精準的鏈接起來。
當子應用發(fā)生切換,iframe保留下來,子應用的容器可能銷毀,但webcomponent依然可以選擇保留,這樣等應用切換回來將webcomponent再掛載回容器上,這樣子應用就可以獲得類似vue的keep-alive的能力。
webcomponent和proxy的降級方案
在非降級場景下,子應用的dom在webcomponent中,運行環(huán)境在iframe中,iframe對dom的操作通過proxy來代理到webcomponent上。
而webcomponent和proxy IE都無法支持,wujie采用另一個的iframe替換webcomponent,用Object.defineProperty替換proxy來做代理的方案。
降級的行為由框架判斷,當瀏覽器不支持時自動降級。
降級后,應用之間也保證了絕對的隔離度。
代碼無需做任何改動,之前的預加載、?;钸€有通信的代碼都生效,用戶不需要為了降級做額外的代碼改動導致降級前后運行的代碼不一致。
五、實踐總結(jié)
常見問題
(1)跨域問題和cors設置
可能的原因分析:
子應用的資源和fetch接口的請求都在主域名發(fā)起,所以會有跨域問題,子應用必須做 cors 設置。
資源或接口請求沒有攜帶 cookie子應用本身是用fetch發(fā)起請求,需要將子應用fetch的credentials設置為include,這樣cookie才會攜帶上去。
或者在主應用自定義fetch并將fetch的credentials設置為include。
(2)子應用彈框位置不正確
冒泡系列組件(比如下拉框)彈出位置不正確。
解決方案:子應用將body設置為 position: relative 即可。
子應用彈窗根據(jù)點擊事件的 event.clientY 來確定top位置,但是主應用頭部有導航欄導致位置計算不準確。
解決方案:子應用彈窗dom元素添加 position: fixed 樣式即可。
社區(qū)優(yōu)秀插件
wujie-polyfill
由于wujie(無界)采用的是WebComponents + iframe 來是腳本沙箱和樣式隔離,該倉庫用于彌補該方案的在特定的景下的不足。
插件列表:
LocationReloadPlugin (頁面刷新插件)
EventTargetPlugin (事件目標插件)
WindowGetterPlugin (window獲取插件)
WindowMessagePlugin (window通信插件)
DocFullScrollPlugin (全屏插件)
InstanceofPlugin (原型鏈判定插件)
基本上目前常見的子應用各種問題和坑都能在社區(qū)找到解決方案。
以上,我們介紹了微前端在大數(shù)據(jù)產(chǎn)品中的應用背景、應用理由、應用方式和應用原理,當然我們在實踐過程中也不是一帆風順的,中間也踩過不少坑走過不少彎路,也遇到過一些非常棘手一時無法解決的問題,所幸還有很多社區(qū)伙伴給予了很大的支持和幫助,梯度科技也將積極參與開源社區(qū)建設工作,回饋開源社區(qū),為開源社區(qū)持續(xù)提供優(yōu)質(zhì)的代碼與獨立的開源項目。
責任編輯:彭菁
-
模塊
+關(guān)注
關(guān)注
7文章
2695瀏覽量
47431 -
前端
+關(guān)注
關(guān)注
1文章
192瀏覽量
17748 -
代碼
+關(guān)注
關(guān)注
30文章
4779瀏覽量
68521 -
大數(shù)據(jù)
+關(guān)注
關(guān)注
64文章
8882瀏覽量
137394 -
服務端
+關(guān)注
關(guān)注
0文章
66瀏覽量
7004
原文標題:微前端在大數(shù)據(jù)平臺中實際應用案例剖析
文章出處:【微信號:gh_681e57b24d17,微信公眾號:梯度科技】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
評論