微前端的幾種實現(xiàn)方案

iframe

iframehtml 提供的標(biāo)簽涩蜘,能加載其他web應(yīng)用的內(nèi)容,并且它能兼容所有的瀏覽器熏纯,因此同诫,你可以用它來加載任何你想要加載的web應(yīng)用。

iframe最大的特性就是提供了瀏覽器原生的硬隔離方案豆巨,不論是樣式隔離剩辟、js 隔離這類問題統(tǒng)統(tǒng)都能被完美解決。iframe與微前端概念中提到的獨立開發(fā)往扔、獨立維護(hù)、相互隔離非常的吻合熊户。

qiankun技術(shù)圓桌中一篇《關(guān)于微前端Why Not Iframe的思考》萍膛,總結(jié)的很到位,現(xiàn)復(fù)述其中的一段描述

iframe雖然基本能做到微前端所要做的所有事情嚷堡,但它的最大問題也在于他的隔離性無法被突破蝗罗,導(dǎo)致應(yīng)用間上下文無法被共享,隨之帶來開發(fā)體驗蝌戒、產(chǎn)品體驗的問題串塑。

文中對 iframe 的總結(jié):

  • 不是單頁應(yīng)用,不會影響外部的路由地址北苟,無法記住當(dāng)前訪問的頁面地址桩匪,會導(dǎo)致瀏覽器刷新頁面 iframe url 狀態(tài)丟失、后退前進(jìn)按鈕無法使用友鼻。
  • 彈框類的功能無法應(yīng)用到整個大應(yīng)用中傻昙,只能在對應(yīng)的窗口內(nèi)展示闺骚。
  • 由于可能應(yīng)用間不是在相同的域內(nèi),主應(yīng)用的 cookie 要透傳到根域名都不同的子應(yīng)用中才能實現(xiàn)免登錄效果妆档。
  • 每次子應(yīng)用進(jìn)入都是一次瀏覽器上下文重建僻爽、資源重新加載的過程,占用大量資源的同時也在極大地消耗資源贾惦。
  • iframe的特性導(dǎo)致搜索引擎無法獲取到其中的內(nèi)容胸梆,進(jìn)而無法實現(xiàn)應(yīng)用的 seo

Web Components

或許很多小伙伴對Web Components不是很了解,它是由google推出的瀏覽器的原生組件,MDN對Web Components的定義是這樣的:

作為開發(fā)者,我們都知道盡可能多的重用代碼是一個好主意须板。這對于自定義標(biāo)記結(jié)構(gòu)來說通常不是那么容易 — 想想復(fù)雜的HTML(以及相關(guān)的樣式和腳本)碰镜,有時您不得不寫代碼來呈現(xiàn)自定義UI控件,并且如果您不小心的話逼纸,多次使用它們會使您的頁面變得一團(tuán)糟洋措。
Web Components旨在解決這些問題 — 它由三項主要技術(shù)組成,它們可以一起使用來創(chuàng)建封裝功能的定制元素杰刽,可以在你喜歡的任何地方重用菠发,不必?fù)?dān)心代碼沖突。

它的三項主要技術(shù)是指:

  • Custom elements(自定義元素):一組JavaScript API贺嫂,允許您定義custom elements及其行為滓鸠,然后可以在您的用戶界面中按照需要使用它們。
  • Shadow DOM(影子DOM):一組JavaScript API第喳,用于將封裝的“影子”DOM樹附加到元素(與主文檔DOM分開呈現(xiàn))并控制其關(guān)聯(lián)的功能糜俗。通過這種方式,您可以保持元素的功能私有曲饱,這樣它們就可以被腳本化和樣式化悠抹,而不用擔(dān)心與文檔的其他部分發(fā)生沖突。
  • HTML templates(HTML模板):<template> 和 <slot> 元素使您可以編寫不在呈現(xiàn)頁面中顯示的標(biāo)記模板扩淀。然后它們可以作為自定義元素結(jié)構(gòu)的基礎(chǔ)被多次重用楔敌。

通過以上描述,再結(jié)合微前端的概念驻谆,我們來看看Web Components是如何做到微前端:

  • 技術(shù)棧無關(guān):Web Components是瀏覽器原生組件卵凑,那即是在任何框架中都可以使用。
  • 獨立開發(fā):使用Web Components開發(fā)的應(yīng)用無需與其他應(yīng)用間產(chǎn)生任何關(guān)聯(lián)胜臊。
  • 應(yīng)用間隔離:Shadow DOM的特性勺卢,各個引入的微應(yīng)用間可以達(dá)到相互隔離的效果。

綜上所述象对,Web Components是有能力以組件加載的方式將微應(yīng)用整合在一起作為微前端的一種手段黑忱,但不幸的是,Web Components是瀏覽器的新特性,所以它的兼容性不是很好杨何,如果有兼容性要求的項目還是無法使用酱塔,具體請查看can i use。

ESM

ESM是ES Module的縮寫危虱,是Ecma script 2015中提出的一種前端模塊化手段羊娃,那么,它又是如何做到微前端的呢埃跷?其實龙屉,微前端無外乎三大特性叉瘩,無技術(shù)棧限制、應(yīng)用單獨開發(fā),多應(yīng)用整合懂鸵,只要抓住了這三個特性址貌,那就不難理解ESM如何做的了:

  • 無技術(shù)棧限制:ESM加載的只是js內(nèi)容跟伏,無論哪個框架耻姥,最終都要編譯成js,因此厕吉,無論哪種框架酱固,ESM都能加載。
  • 應(yīng)用單獨開發(fā):ESM只是js的一種規(guī)范头朱,不會影響應(yīng)用的開發(fā)模式运悲。
  • 多應(yīng)用整合:只要將微應(yīng)用以ESM的方式暴露出來,就能正常加載项钮。
  • 遠(yuǎn)程加載模塊: ESM能夠直接請求cdn資源班眯,這是它與生俱來的能力。

ESM是能做到微前端的核心思想烁巫,但是它也存在著兼容性這一大弊端署隘,盡管ESM已經(jīng)很優(yōu)秀了,但是大部分老版的瀏覽器仍然無法直接使用亚隙,這也是babel等編譯工具出現(xiàn)的原因定踱,幸運(yùn)的是,他可以通過webpack恃鞋、rollup、esbuild亦歉、snowpack等編譯工具成為兼容性的代碼恤浪。

qiankun

qiankun 特點如下:

  • 基于single-spa封裝,提供了更加開箱即用的 API
  • 技術(shù)棧無關(guān)肴楷,任意技術(shù)棧的應(yīng)用均可 使用/接入水由,不論是 React/Vue/Angular/JQuery 還是其他等框架
  • 子應(yīng)用獨立部署
  • 子應(yīng)用與主應(yīng)用無縫銜接,主應(yīng)用對子應(yīng)用可控赛蔫,子應(yīng)用可獲取主應(yīng)用資源
  • HTML Entry 接入方式砂客,讓你接入微應(yīng)用像使用 iframe 一樣簡單
  • 樣式隔離泥张,確保微應(yīng)用之間樣式互相不干擾
  • JS 沙箱,確保微應(yīng)用之間 全局變量/事件 不沖突
  • 資源預(yù)加載鞠值,在瀏覽器空閑時間預(yù)加載未打開的微應(yīng)用資源媚创,加速微應(yīng)用打開速度
  • umi 插件,提供了 @umijs/plugin-qiankun 供 umi 應(yīng)用一鍵切換成微前端架構(gòu)系統(tǒng)除了最后一點拓展以外彤恶,微前端想要達(dá)到的效果都已經(jīng)達(dá)到钞钙。

qiankun原理

微前端實現(xiàn)原理是 主工程在運(yùn)行時獲取應(yīng)用配置,然后注冊應(yīng)用和路由声离,先加載主應(yīng)用(菜單等)芒炼,當(dāng)url 地址變化時,通過路由管理器和應(yīng)用管理器動態(tài)加載對應(yīng)的子應(yīng)用

路由管理器是指把所有子應(yīng)用的路由統(tǒng)一放在一個總路由里管理术徊,應(yīng)用管理器是把所有子應(yīng)用打包后的實例放在一個應(yīng)用管理器里本刽,當(dāng)URL和路由管理器中的子應(yīng)用路由匹配時,通過應(yīng)用管理器加載對應(yīng)的子應(yīng)用

actions 通信原理
Actions 通信方案是通過全局狀態(tài)池和觀察者函數(shù)進(jìn)行應(yīng)用間通信赠涮,比較適合業(yè)務(wù)劃分清晰子寓,應(yīng)用間通信較少的微前端應(yīng)用場景。

qiankun 內(nèi)部提供了 initGlobalState 方法用于注冊 MicroAppStateActions 實例用于通信世囊,該實例有三個方法别瞭,分別是:

  • setGlobalState:設(shè)置 globalState - 設(shè)置新的值時,內(nèi)部將執(zhí)行 淺檢查株憾,如果檢查到 globalState 發(fā)生改變則觸發(fā)通知蝙寨,通知到所有的 觀察者 函數(shù)。
  • onGlobalStateChange:注冊 觀察者 函數(shù) - 響應(yīng) globalState 變化嗤瞎,在 globalState 發(fā)生改變時觸發(fā)該 觀察者 函數(shù)墙歪。
  • offGlobalStateChange:取消 觀察者 函數(shù) - 該實例不再響應(yīng) globalState 變化。

Actions 通信方案也存在一些優(yōu)缺點贝奇,優(yōu)點如下:

  • 使用簡單虹菲;
    -官方支持性高;
  • 適合通信較少的業(yè)務(wù)場景掉瞳;

缺點如下:

  • 子應(yīng)用獨立運(yùn)行時毕源,需要額外配置無 Actions 時的邏輯;
  • 子應(yīng)用需要先了解狀態(tài)池的細(xì)節(jié)陕习,再進(jìn)行通信霎褐;
  • 由于狀態(tài)池?zé)o法跟蹤,通信場景較多時该镣,容易出現(xiàn)狀態(tài)混亂冻璃、維護(hù)困難等問題;

Shared 通信原理
適合需要跟蹤通信狀態(tài),子應(yīng)用具備獨立運(yùn)行能力省艳,較為復(fù)雜的微前端應(yīng)用娘纷。

Shared 通信方案的原理就是,主應(yīng)用基于 redux 維護(hù)一個狀態(tài)池跋炕,通過 shared 實例暴露一些方法給子應(yīng)用使用赖晶。同時,子應(yīng)用需要單獨維護(hù)一份 shared 實例枣购,在獨立運(yùn)行時使用自身的 shared 實例嬉探,在嵌入主應(yīng)用時使用主應(yīng)用的 shared 實例,這樣就可以保證在使用和表現(xiàn)上的一致性棉圈。

Shared 通信方案需要自行維護(hù)狀態(tài)池涩堤,這樣會增加項目的復(fù)雜度。好處是可以使用市面上比較成熟的狀態(tài)管理工具分瘾,如 redux胎围、mobx,可以有更好的狀態(tài)管理追蹤和一些工具集德召。

Shared 通信方案要求父子應(yīng)用都各自維護(hù)一份屬于自己的 shared 實例白魂,同樣會增加項目的復(fù)雜度。好處是子應(yīng)用可以完全獨立于父應(yīng)用運(yùn)行(不依賴狀態(tài)池)上岗,子應(yīng)用也能以最小的改動被嵌入到其他 第三方應(yīng)用 中福荸。

Shared 通信方案也可以幫助主應(yīng)用更好的管控子應(yīng)用。子應(yīng)用只可以通過 shared 實例來操作狀態(tài)池肴掷,可以避免子應(yīng)用對狀態(tài)池隨意操作引發(fā)的一系列問題敬锐。主應(yīng)用的 Shared 相對于子應(yīng)用來說是一個黑箱,子應(yīng)用只需要了解 Shared 所暴露的 API 而無需關(guān)心實現(xiàn)細(xì)節(jié)呆瞻。

優(yōu)點:

  • 可以自由選擇狀態(tài)管理庫台夺,更好的開發(fā)體驗。 - 比如 redux 有專門配套的開發(fā)工具可以跟蹤狀態(tài)的變化痴脾。
  • 子應(yīng)用無需了解主應(yīng)用的狀態(tài)池實現(xiàn)細(xì)節(jié)颤介,只需要了解 shared 的函數(shù)抽象,實現(xiàn)一套自身的 shared 甚至空 shared 即可赞赖,可以更好的規(guī)范子應(yīng)用開發(fā)滚朵。
  • 子應(yīng)用無法隨意污染主應(yīng)用的狀態(tài)池,只能通過主應(yīng)用暴露的 shared 實例的特定方法操作狀態(tài)池前域,從而避免狀態(tài)池污染產(chǎn)生的問題始绍。
  • 子應(yīng)用將具備獨立運(yùn)行的能力,Shared 通信使得父子應(yīng)用有了更好的解耦性话侄。

缺點:

  • 主應(yīng)用需要單獨維護(hù)一套狀態(tài)池,會增加維護(hù)成本和項目復(fù)雜度;
  • 子應(yīng)用需要單獨維護(hù)一份 shared 實例年堆,會增加維護(hù)成本吞杭;

EMP

EMP是由歡聚時代業(yè)務(wù)中臺自主研發(fā)的最年輕的單頁微前端解決方案

有如下特性:

  • 基于 Webpack5 的新特性 Module Federation 實現(xiàn),達(dá)到第三方依賴共享变丧,減少不必要的代碼引入的目的芽狗,什么是Module Federation這里就不再贅述。
  • 每個微應(yīng)用獨立部署運(yùn)行痒蓬,并通過cdn的方式引入主程序中童擎,因此只需要部署一次,便可以提供給任何基于Module Federation的應(yīng)用使用攻晒。并且此部分代碼是遠(yuǎn)程引入顾复,無需參與應(yīng)用的打包。
  • 動態(tài)更新微應(yīng)用:EMP是通過cdn加載微應(yīng)用鲁捏,因此每個微應(yīng)用中的代碼有變動時芯砸,無需重新打包發(fā)布新的整合應(yīng)用便能加載到最新的微應(yīng)用。
  • 去中心化给梅,每個微應(yīng)用間都可以引入其他的微應(yīng)用假丧,無中心應(yīng)用的概念。
  • 跨技術(shù)棧組件式調(diào)用动羽,提供了在主應(yīng)用框架中可以調(diào)用其他框架組件的能力(目前已支持互相調(diào)用的框架及使用方式請參閱官方文檔)包帚。
  • 按需加載,開發(fā)者可以選擇只加載微應(yīng)用中需要的部分运吓,而不是強(qiáng)制只能將整個應(yīng)用全部加載渴邦。
  • 應(yīng)用間通信,每一個應(yīng)用都可以進(jìn)行狀態(tài)共享羽德,就像在使用npm模塊進(jìn)行開發(fā)一樣便捷几莽。
  • 生成對應(yīng)技術(shù)棧模板,它能像cerate-react-app一樣宅静,也能像create-vue-app一樣章蚣,通過指令一鍵搭建好開發(fā)環(huán)境,減少開發(fā)者的負(fù)擔(dān)姨夹。
  • 遠(yuǎn)程拉取ts聲明文件纤垂,emp-cli中內(nèi)置了拉取遠(yuǎn)程應(yīng)用中代碼聲明文件的能力,讓使用ts開發(fā)的開發(fā)者不再為代碼報錯而煩惱磷账。

總結(jié)

各解決方案的利弊:

  • iframe 可以直接加載其他應(yīng)用峭沦,但無法做到單頁導(dǎo)致許多功能無法正常在主應(yīng)用中展示。
  • web ComponentsESM 是瀏覽器提供給開發(fā)者的能力逃糟,能在單頁中實現(xiàn)微前端吼鱼,不過后者需要做好代碼隔離蓬豁,并且他們都是瀏覽器的新特性,都存在兼容性問題菇肃,微前端方面的探索也不成熟地粪,只能作為面向未來的微前端手段。
  • qiankun 基本上可以稱為單頁版的 iframe琐谤,具有沙箱隔離及資源預(yù)加載的特點蟆技,幾乎無可挑剔。
  • EMP 作為最年輕微前端解決方案斗忌,也是吸收了許多web優(yōu)秀特性才誕生的质礼,它在實現(xiàn)微前端的基礎(chǔ)上,擴(kuò)充了跨應(yīng)用狀態(tài)共享织阳、跨框架組件調(diào)用眶蕉、遠(yuǎn)程拉取ts聲明文件、動態(tài)更新微應(yīng)用等能力陈哑。同時妻坝,EMP 能做到第三方依賴的共享,使代碼盡可能地重復(fù)利用惊窖,減少加載的內(nèi)容刽宪。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市界酒,隨后出現(xiàn)的幾起案子圣拄,更是在濱河造成了極大的恐慌,老刑警劉巖毁欣,帶你破解...
    沈念sama閱讀 221,635評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件庇谆,死亡現(xiàn)場離奇詭異,居然都是意外死亡凭疮,警方通過查閱死者的電腦和手機(jī)饭耳,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,543評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來执解,“玉大人寞肖,你說我怎么就攤上這事∷ル纾” “怎么了新蟆?”我有些...
    開封第一講書人閱讀 168,083評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長右蕊。 經(jīng)常有香客問我琼稻,道長,這世上最難降的妖魔是什么饶囚? 我笑而不...
    開封第一講書人閱讀 59,640評論 1 296
  • 正文 為了忘掉前任帕翻,我火速辦了婚禮鸠补,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘熊咽。我一直安慰自己莫鸭,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 68,640評論 6 397
  • 文/花漫 我一把揭開白布横殴。 她就那樣靜靜地躺著,像睡著了一般卿拴。 火紅的嫁衣襯著肌膚如雪衫仑。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,262評論 1 308
  • 那天堕花,我揣著相機(jī)與錄音文狱,去河邊找鬼。 笑死缘挽,一個胖子當(dāng)著我的面吹牛瞄崇,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播壕曼,決...
    沈念sama閱讀 40,833評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼苏研,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了腮郊?” 一聲冷哼從身側(cè)響起摹蘑,我...
    開封第一講書人閱讀 39,736評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎轧飞,沒想到半個月后衅鹿,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,280評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡过咬,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,369評論 3 340
  • 正文 我和宋清朗相戀三年大渤,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片掸绞。...
    茶點故事閱讀 40,503評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡泵三,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出集漾,到底是詐尸還是另有隱情切黔,我是刑警寧澤,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布具篇,位于F島的核電站纬霞,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏驱显。R本人自食惡果不足惜诗芜,卻給世界環(huán)境...
    茶點故事閱讀 41,870評論 3 333
  • 文/蒙蒙 一瞳抓、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧伏恐,春花似錦孩哑、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,340評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至销凑,卻和暖如春丛晌,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背斗幼。 一陣腳步聲響...
    開封第一講書人閱讀 33,460評論 1 272
  • 我被黑心中介騙來泰國打工澎蛛, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人蜕窿。 一個月前我還...
    沈念sama閱讀 48,909評論 3 376
  • 正文 我出身青樓谋逻,卻偏偏與公主長得像,于是被迫代替她去往敵國和親桐经。 傳聞我的和親對象是個殘疾皇子毁兆,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,512評論 2 359

推薦閱讀更多精彩內(nèi)容

  • 前言 隨著技術(shù)的發(fā)展,前端應(yīng)用承載的內(nèi)容也日益復(fù)雜次询,基于此而產(chǎn)生的各種問題也應(yīng)運(yùn)而生荧恍,從MPA(Multi-Pag...
    維李設(shè)論閱讀 1,544評論 0 0
  • —— 一個基于single-spa的vue2升級至vue3的項目Author 柯雨 Date 2021-01-2...
    我們都是架構(gòu)師閱讀 1,005評論 0 4
  • 1.路由分發(fā)式。通過HTTP服務(wù)器的反向代理功能屯吊,將請求路由到對應(yīng)的應(yīng)用上 路由分發(fā)式微前端送巡,即通過路由將不同的業(yè)...
    大呂澤閱讀 930評論 0 0
  • 最近負(fù)責(zé)的新項目用到了qiankun,寫篇文章分享下實戰(zhàn)中遇到的一些問題和思考盒卸。 示例代碼: https://gi...
    fengxianqi閱讀 3,322評論 2 20
  • 推薦指數(shù): 6.0 書籍主旨關(guān)鍵詞:特權(quán)骗爆、焦點、注意力蔽介、語言聯(lián)想摘投、情景聯(lián)想 觀點: 1.統(tǒng)計學(xué)現(xiàn)在叫數(shù)據(jù)分析,社會...
    Jenaral閱讀 5,724評論 0 5