如何接地气地接入微前端?
一 前言
微前端,這個(gè)概念已經(jīng)在國(guó)內(nèi)不止一次的登上各大熱門話題,它所解決的問(wèn)題也很明顯,這幾個(gè)微前端所提到的痛點(diǎn)在我們團(tuán)隊(duì)所維護(hù)的項(xiàng)目中也是非常凸顯。
但我始終認(rèn)為,一個(gè)新的技術(shù)、浪潮,每每被討論最熱門的一定是他背后所代表的杰出思考。
"微前端就是...xx 框架,xx 技術(shù)"
這種話就有點(diǎn)把這種杰出的思路說(shuō)的局限了,我只能認(rèn)為他是外行人,來(lái)蹭這個(gè)詞的熱度。
在我所負(fù)責(zé)的項(xiàng)目和團(tuán)隊(duì)中,已經(jīng)有非常大的存量技術(shù)棧和頁(yè)面已經(jīng)在線上運(yùn)行,任何迭代升級(jí)都必須要保證小心翼翼,萬(wàn)無(wú)一失。
可以說(shuō),從一定程度來(lái)講,微前端所帶來(lái)的這些好處是從用戶體驗(yàn)和技術(shù)維護(hù)方面的,對(duì)業(yè)務(wù)的價(jià)值并不能量化體現(xiàn),落地這項(xiàng)技術(shù)秉著既要也要還要的指導(dǎo)方針。
我們對(duì)存量技術(shù)棧一定需要保持敬畏,隔離,影響范圍可控的幾個(gè)基本要素,然后再考慮落地實(shí)施微前端方案。
所以,在這個(gè)基本要素和指導(dǎo)方針下,要落地這項(xiàng)新的技術(shù),一定要充分了解當(dāng)前改造站點(diǎn)所存在的技術(shù)方案、占比以及當(dāng)前成熟的微前端框架已提供的能力差異,切勿生搬硬套。
二 背景
我所在團(tuán)隊(duì)維護(hù)的項(xiàng)目都是些 PC 操作后臺(tái)(Workstation),這些工作臺(tái)會(huì)存在不同的國(guó)家,不同時(shí)區(qū),不同合作方等等問(wèn)題。
如果需要開發(fā)一個(gè)新的頁(yè)面需求,很可能投入進(jìn)來(lái)的開發(fā)人員都來(lái)自不同團(tuán)隊(duì),此時(shí)我們要在完成現(xiàn)有需求的同時(shí)還需要保證多個(gè)管理頁(yè)面的風(fēng)格統(tǒng)一,設(shè)計(jì)規(guī)范統(tǒng)一,組件統(tǒng)一,交互行為統(tǒng)一這非常困難。
當(dāng)該業(yè)務(wù)需要遷移到另外一個(gè)工作臺(tái)時(shí),雖然需要保持邏輯一致,但導(dǎo)航欄、主題等卻不同。
當(dāng)前存量的方案都是采用 Java 直接進(jìn)行 Template 渲染出 HTML,經(jīng)過(guò)前面幾代前輩的迭代,不同系統(tǒng)中已經(jīng)存在幾種不同技術(shù)棧產(chǎn)出的頁(yè)面。
雖然都是 React 來(lái)實(shí)現(xiàn)的,但是前輩們都非常能折騰,沒有一個(gè)是按照常規(guī) React 組件形式開發(fā)出來(lái)的。
比如:
- 大部分頁(yè)面是通過(guò)一份 JSON 配置,消費(fèi)組件生成的頁(yè)面。
- 部分頁(yè)面是通過(guò)另外一個(gè)團(tuán)隊(duì)定義的 JSON 配置消費(fèi)組件生成的,與上面 JSON 完全不一樣。
- 還有一部分頁(yè)面,是通過(guò)一套頁(yè)面發(fā)布平臺(tái)提供的 JS Bundle 加載出來(lái)的。
面對(duì)這樣的技術(shù)背景下,除了微笑的喊 MMP,含淚說(shuō)著自己聽不懂的話(存在即合理,不難要你干嘛?),還得接地氣地出這樣一個(gè)落地方案。
三 方案 & 流程圖
首先,需要明確的分析出站點(diǎn)所有頁(yè)面,所需要加載的通用特性:
上述是精簡(jiǎn)過(guò)后的一些通用功能特性,這里簡(jiǎn)單做下介紹:
- Layout Loader:用于加載不同工作臺(tái)的導(dǎo)航
- DADA Loader:用于加載 JSON 配置的頁(yè)面
- Source Code Loader:用于加載 JS Bundle
- Micro Loader:用于處理微前端加載
- Log Report:用于日志埋點(diǎn)
- Time Zone:用于切換時(shí)區(qū)
- i18n:用于切換多語(yǔ)言
- Guider:用于統(tǒng)一管控用戶引導(dǎo)
除此以外可能還會(huì)存在以下這些頁(yè)面擴(kuò)展能力:
- 安全監(jiān)控
- 流量管控
- 彈窗管控
- 問(wèn)卷調(diào)查
- 答疑機(jī)器人
粗略統(tǒng)一歸類后來(lái)看,頁(yè)面的大體加載流程應(yīng)該是這樣:
四 實(shí)現(xiàn)細(xì)則
基于上述一個(gè)加載思路,首先需要做的是頁(yè)面加載路徑收口,需要保證所有頁(yè)面的加載入口是在一個(gè)統(tǒng)一的 Loader 下,然后才可以較為系統(tǒng)的處理所有頁(yè)面的加載生命周期。
在收斂的同時(shí),同樣需要保持開放,對(duì)核心加載路徑要保持插件化開放,隨時(shí)支持不同的擴(kuò)展能力,渲染技術(shù)棧接入。
1 插件機(jī)制
所以,在主路徑上,通過(guò) Loader 加載配置進(jìn)行處理,這份配置在主路徑中提供上下文,然后交由插件進(jìn)行消費(fèi),如圖所示:
舉個(gè)例子,拿一個(gè)獨(dú)立的 JS Bundle 類型的子應(yīng)用來(lái)說(shuō):
<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 & countryresource: {js: "/index.js",css: "/index.css",},},{ container: document.querySelector("#root") }); </script>通過(guò)上述的 Plugin 引入,即可開啟和消費(fèi)不同的配置。
這里引入了 Layout Plugin,該插件會(huì)消費(fèi) hfType 字段然后去加載對(duì)于的 Layout 資源提供 Container 交給下一個(gè)環(huán)節(jié)。
按照配置,當(dāng)前頁(yè)面開啟了微前端,那么 Micro Loader 將會(huì)消費(fèi)提供下來(lái)的 Container,然后建立沙箱(這里基于 qiankun),再提供 Container 出來(lái)。
最后交由 SourceCode Plugin 進(jìn)行 Bundle 加載運(yùn)行和渲染。如果這里是另外一種渲染協(xié)議或者技術(shù)棧,則可以根據(jù)不同配置交由不同插件消費(fèi) Container。
這個(gè)過(guò)程中,每個(gè)環(huán)節(jié)的插件是不依賴的,可插拔的。
比如:
如果不加載 Layout Plugin 將不會(huì)消費(fèi) hfType 字段,也就不會(huì)將 Layout 插件邏輯注入到getContainer方法中,那么將直接得到由最外層下穿的 Container 進(jìn)行渲染,也就不會(huì)有菜單相關(guān)透出。
如果不加載 Micro Plugin 同樣不會(huì)有微前端的邏輯注入,也就不會(huì)建立沙箱,那么頁(yè)面渲染流程將會(huì)按照常規(guī)模式繼續(xù)運(yùn)行。
2 安全遷移
對(duì)于我所在團(tuán)隊(duì)負(fù)責(zé)的項(xiàng)目來(lái)說(shuō),萬(wàn)萬(wàn)做不得一刀切的方案,所以針對(duì)現(xiàn)有存量頁(yè)面,需要完整分析當(dāng)前存量技術(shù)棧:
針對(duì)上述存量頁(yè)面來(lái)說(shuō),需要從左到右分批進(jìn)行頁(yè)面級(jí)別控制上線部署,對(duì)于左側(cè)部分頁(yè)面甚至需要做些項(xiàng)目改造后才可部署接入上線。
這類遷移測(cè)試需要處理出一套自動(dòng)化 e2e 測(cè)試流程,通過(guò)分批遷移同時(shí)梳理出 微前端注冊(cè)表 。
有了這兩項(xiàng)流程保證及范圍控制,當(dāng)前方案所上線內(nèi)容完全可控,剩下要處理的大部分就是較為重復(fù)的體力活了,覆蓋率也可量化。
3 微前端形態(tài)
按照上述方案遷移,那么預(yù)期的微前端形態(tài)將會(huì)是:
- 每個(gè)開啟微前端的頁(yè)面都可成為主應(yīng)用。
- 微前端是插件可選項(xiàng),如果因?yàn)槲⑶岸藢?dǎo)致的業(yè)務(wù)異常可隨時(shí)關(guān)閉。
- 同為微前端的頁(yè)面路由相互之間切換可實(shí)現(xiàn)局部刷新形態(tài),而跳轉(zhuǎn)至非微前端注冊(cè)表中的頁(yè)面則會(huì)直接頁(yè)面跳轉(zhuǎn)。隨著微前端頁(yè)面覆蓋率提高,局部刷新的覆蓋率也會(huì)逐漸提高。
- 可通過(guò)不同擴(kuò)展插件,加載不同技術(shù)棧類型的存量頁(yè)面,轉(zhuǎn)換為對(duì)應(yīng)子應(yīng)用。
在 SchemaResolver 中的注冊(cè)和調(diào)用路徑如下:
五 總結(jié)
透過(guò)技術(shù)看本質(zhì),微前端所代表的杰出思維,才是真正解決具體問(wèn)題關(guān)鍵所在,只有解決了具體的業(yè)務(wù)問(wèn)題,這項(xiàng)技術(shù)才有價(jià)值轉(zhuǎn)換。
不要為了微前端做微前端,不要為了小程序做小程序。
當(dāng)前,通過(guò) SchemaResolver,可以針對(duì)不同角色提供不同的開放能力:
- 針對(duì)平臺(tái)管理員,提供插件能力開放全局?jǐn)U展能力。
- 針對(duì)頁(yè)面開發(fā)者,提供標(biāo)準(zhǔn)化接入方案路徑,提供多種技術(shù)棧接入能力,并無(wú)感知提供微前端,多語(yǔ)言,埋點(diǎn),菜單,主題加載等能力。解耦了不同系統(tǒng)公共能力,同時(shí),這種方式可以讓頁(yè)面開發(fā)者快速將具體業(yè)務(wù)邏輯遷移到其他平臺(tái)。
- 針對(duì)第三方接入者,不需要關(guān)心了解系統(tǒng)菜單、主題接入方式,提供統(tǒng)一的接入口徑,通過(guò)微前端隔離技術(shù)棧、隔離子應(yīng)用樣式。最后通過(guò)統(tǒng)一的頁(yè)面系統(tǒng)管控,輕松入住對(duì)應(yīng)平臺(tái),同時(shí)可以全局看到站點(diǎn)頁(yè)面情況。
原文鏈接:https://developer.aliyun.com/article/779730?
版權(quán)聲明:本文內(nèi)容由阿里云實(shí)名注冊(cè)用戶自發(fā)貢獻(xiàn),版權(quán)歸原作者所有,阿里云開發(fā)者社區(qū)不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。具體規(guī)則請(qǐng)查看《阿里云開發(fā)者社區(qū)用戶服務(wù)協(xié)議》和《阿里云開發(fā)者社區(qū)知識(shí)產(chǎn)權(quán)保護(hù)指引》。如果您發(fā)現(xiàn)本社區(qū)中有涉嫌抄襲的內(nèi)容,填寫侵權(quán)投訴表單進(jìn)行舉報(bào),一經(jīng)查實(shí),本社區(qū)將立刻刪除涉嫌侵權(quán)內(nèi)容。總結(jié)
以上是生活随笔為你收集整理的如何接地气地接入微前端?的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 阿里 双11 同款流控降级组件 Sent
- 下一篇: 还在自建代码仓库?阿里云的这款企业级代码