https://blog.csdn.net/qq_41694291/article/details/113842872
答題分為以下幾點(diǎn)
- 什么是微前端,為什么要用(解決什么問題)
- 優(yōu)勢
- 常見的微前端方案有哪些
- 我們用的是哪個(gè)微前端方案
- qiankun與single-spa相比好在什么地方
什么是微前端,為什么要用(解決什么問題)
概念:微前端的概念借鑒于后端的微服務(wù),一般以業(yè)務(wù)功能為拆分單元
解決問題:大型項(xiàng)目的變更、擴(kuò)展、維護(hù)困難的問題
優(yōu)勢
- 技術(shù)兼容性好、子應(yīng)用可以基于不同的技術(shù)框架
- 拆分后體積變小,代碼內(nèi)聚性更強(qiáng),每個(gè)子應(yīng)用只是一個(gè)業(yè)務(wù)模塊
- 能夠獨(dú)立開發(fā)、編譯、部署
- 耦合性低,可獨(dú)自開發(fā),互不干擾
- 可維護(hù)和擴(kuò)展性好,可專門升級(jí)某一個(gè)功能
缺點(diǎn)
總體積變大,插件可上傳cdn,但公共函數(shù)資源不便于共享
常見的微前端方案有哪些
iframe:隔離性和兼容性好,性能和使用感差(性能差因?yàn)椴粫?huì)有緩存,每次重新加載)
基座模式:基于路由分發(fā),由基座監(jiān)聽路由變化,加載不同的應(yīng)用,實(shí)現(xiàn)應(yīng)用解耦,single-spa、qiankun
組合式集成:組件單獨(dú)打包發(fā)布,類似于npm包
EMP:主要基于Webpack5 Module Federation
web components:micro-app(京東的)
Web Components
微前端(Micro Frontends)是一種前端架構(gòu)風(fēng)格,通過將大型單體應(yīng)用程序分解為一組小型、自治的功能塊,來提高應(yīng)用程序的可維護(hù)性、可擴(kuò)展性和可重用性。
Web Components 是一組瀏覽器標(biāo)準(zhǔn)和 API,允許開發(fā)者創(chuàng)建可重用的自定義 HTML 元素和組件。它由三個(gè)主要技術(shù)組成:Custom Elements、Shadow DOM 和 HTML Templates。Web Components 提供了一種用于封裝和復(fù)用 HTML、CSS 和 JavaScript 的機(jī)制,類似于 React 和 Vue 等現(xiàn)代前端框架提供的組件化機(jī)制。
微前端和 Web Components 的結(jié)合,即為微前端 WebComponents。在微前端 WebComponents 架構(gòu)中,每個(gè)小型功能塊都被打包為一個(gè) Web Component,這些 Web Components 可以獨(dú)立開發(fā)、測試和部署。在運(yùn)行時(shí),這些 Web Components 被加載到一個(gè)主應(yīng)用程序中,以組成一個(gè)完整的應(yīng)用程序。這種架構(gòu)風(fēng)格使得應(yīng)用程序更易于擴(kuò)展、升級(jí)和維護(hù),同時(shí)也可以提高開發(fā)效率和團(tuán)隊(duì)協(xié)作能力。
微前端 WebComponents 架構(gòu)中的主應(yīng)用程序負(fù)責(zé)加載和管理所有子應(yīng)用程序,同時(shí)還提供了一些公共的基礎(chǔ)設(shè)施,例如路由、狀態(tài)管理和通信機(jī)制等。每個(gè)子應(yīng)用程序都是一個(gè)自治的 Web Component,它們可以使用任何前端框架或庫來實(shí)現(xiàn)功能,甚至可以使用不同的技術(shù)棧來開發(fā)。在運(yùn)行時(shí),這些子應(yīng)用程序可以被獨(dú)立部署和升級(jí),不會(huì)影響到整個(gè)應(yīng)用程序的穩(wěn)定性和可用性。
micro-app
https://juejin.cn/post/7210747150815936569#heading-35
micro-app并沒有沿襲single-spa的思路,而是借鑒了 WebComponents 的思想,通過 CustomElement 結(jié)合自定義的 ShadowDom,將微前端封裝成一個(gè)類 WebComponents 組件,從而實(shí)現(xiàn)微前端的組件化渲染。并且由于自定義 ShadowDom 的隔離特性,micro-app不需要像single-spa和qiankun一樣要求子應(yīng)用修改渲染邏輯并暴露出方法,也不需要修改 webpack 配置,是目前市面上接入微前端成本最低的方案。
為什么不用iframe
iframe 最大的特性就是提供了瀏覽器原生的硬隔離方案,不論是樣式隔離、js 隔離這類問題統(tǒng)統(tǒng)都能被完美解決。但他的最大問題也在于他的隔離性無法被突破,導(dǎo)致應(yīng)用間上下文無法被共享,隨之帶來的開發(fā)體驗(yàn)、產(chǎn)品體驗(yàn)的問題。
- url 不同步。瀏覽器刷新 iframe url 狀態(tài)丟失、后退前進(jìn)按鈕無法使用。
- UI 不同步,DOM 結(jié)構(gòu)不共享。想象一下屏幕右下角 1/4 的 iframe 里來一個(gè)帶遮罩層的彈框,同時(shí)我們要求這個(gè)彈框要瀏覽器居中顯示,還要瀏覽器 resize 時(shí)自動(dòng)居中..
- 全局上下文完全隔離,內(nèi)存變量不共享。iframe 內(nèi)外系統(tǒng)的通信、數(shù)據(jù)同步等需求,主應(yīng)用的 cookie 要透傳到根域名都不同的子應(yīng)用中實(shí)現(xiàn)免登效果。
- 慢。每次子應(yīng)用進(jìn)入都是一次瀏覽器上下文重建、資源重新加載的過程。
我們用的是哪個(gè)微前端方案
我們采用的是qiankun,主要思路是將一個(gè)大應(yīng)用,拆分為更小的、可獨(dú)立開發(fā)、測試、部署的子應(yīng)用。
傳統(tǒng)的大型項(xiàng)目:所有模塊都在一個(gè)應(yīng)用里,由應(yīng)用本身負(fù)責(zé)路由管理,屬于應(yīng)用分發(fā)路由方式
拆分微應(yīng)用的項(xiàng)目:屬于基座模式下的系統(tǒng)架構(gòu),各應(yīng)用互相獨(dú)立,單獨(dú)運(yùn)行在不同的服務(wù)上,基座(基座一般是用戶最終訪問的應(yīng)用)根據(jù)路由去加載不同的應(yīng)用到頁面上,即路由分發(fā)應(yīng)用方式
qiankun與single-spa對(duì)比
微前端主要需要解決的問題有兩個(gè)
- 應(yīng)用加載與切換
-
應(yīng)用隔離與通信
image.png
qiankun和single-spa對(duì)比

activePath與當(dāng)前的hash對(duì)比一致
shadow dom 怎么處理antd 的modal樣式問題的
https://cloud.tencent.com/developer/beta/article/2212257
一些組件可能會(huì)越過 Shadow Boundary 到外部 Document Tree 插入節(jié)點(diǎn),而這部分節(jié)點(diǎn)的樣式就會(huì)丟失;比如 antd 的 Modal 就會(huì)渲染節(jié)點(diǎn)至 ducument.body ,引發(fā)樣式丟失
針對(duì)剛才的 antd 場景你可以通過他們提供的 ConfigProvider.getPopupContainer API 來指定在 Shadow Tree 內(nèi)部的節(jié)點(diǎn)為掛載節(jié)點(diǎn),但另外一些其他的組件庫,或者你的一些代碼也會(huì)遇到同樣的問題,需要你額外留心。
此外 Shadow DOM 場景下還會(huì)有一些額外的事件處理、邊界處理等問題
qiankun是怎么做到技術(shù)棧無關(guān)的
1、通信協(xié)議的制定和實(shí)現(xiàn)
- 基于瀏覽器提供的“postMessage”接口實(shí)現(xiàn)通用的通信協(xié)議,通過該協(xié)議,不同的字應(yīng)用之間可以進(jìn)行數(shù)據(jù)傳輸和通信,實(shí)現(xiàn)了子應(yīng)用的解耦,
- 該協(xié)議定義了一些標(biāo)準(zhǔn)的消息格式和字段,從而保證了不同技術(shù)棧之間的兼容性和通用性。
- 同時(shí),qiankun 還提供了一些 API,可以方便地進(jìn)行消息的發(fā)送和接收。
2、模塊加載器設(shè)計(jì)和實(shí)現(xiàn)
- qiankun 內(nèi)部使用了一個(gè)獨(dú)立的模塊加載器來加載和執(zhí)行不同的子應(yīng)用。該加載器可以根據(jù)不同的子應(yīng)用需求,選擇合適的技術(shù)棧進(jìn)行加載和執(zhí)行。
- 加載器還支持動(dòng)態(tài)加載和卸載子應(yīng)用,從而實(shí)現(xiàn)了應(yīng)用的動(dòng)態(tài)擴(kuò)展和升級(jí)。
- 在加載子應(yīng)用時(shí),加載器會(huì)對(duì)子應(yīng)用的代碼進(jìn)行適當(dāng)?shù)霓D(zhuǎn)換和處理,從而保證了不同技術(shù)棧之間的兼容性和互相隔離性。
3、沙箱設(shè)計(jì)與實(shí)現(xiàn)(single spa沒有)
- 使用了一個(gè)沙箱來隔離不同子應(yīng)用之間的代碼和數(shù)據(jù)。
- 該沙箱可以在不同技術(shù)棧之間進(jìn)行隔離,并且支持在子應(yīng)用中使用全局變量和函數(shù)。
- 沙箱的實(shí)現(xiàn)依賴于一些瀏覽器提供的安全特性,如 iframe 和 Content Security Policy(CSP),從而保證了應(yīng)用的安全性。
模塊加載器
微前端框架 qiankun 內(nèi)部使用了一個(gè)獨(dú)立的模塊加載器來加載和執(zhí)行不同的子應(yīng)用,該加載器實(shí)現(xiàn)技術(shù)棧無關(guān)的特性。具體來說,模塊加載器的設(shè)計(jì)和實(shí)現(xiàn)主要包括以下幾個(gè)方面:
加載子應(yīng)用的配置:在加載子應(yīng)用時(shí),模塊加載器需要通過一些配置信息來了解子應(yīng)用的相關(guān)信息。這些信息包括子應(yīng)用的名稱、入口 URL、運(yùn)行時(shí)參數(shù)等。模塊加載器會(huì)根據(jù)這些配置信息來選擇合適的技術(shù)棧進(jìn)行加載和執(zhí)行。
加載子應(yīng)用的代碼:模塊加載器會(huì)通過瀏覽器提供的動(dòng)態(tài)創(chuàng)建 script 標(biāo)簽的方式,加載子應(yīng)用的代碼。在加載代碼時(shí),模塊加載器會(huì)對(duì)代碼進(jìn)行適當(dāng)?shù)霓D(zhuǎn)換和處理,以保證不同技術(shù)棧之間的兼容性和互相隔離性。例如,在加載 React 應(yīng)用時(shí),模塊加載器會(huì)通過 Babel 轉(zhuǎn)譯 ES6 代碼和 JSX 語法,以保證在不支持這些語法的瀏覽器中也能夠正常運(yùn)行。
執(zhí)行子應(yīng)用的代碼:加載器在加載子應(yīng)用代碼后,需要執(zhí)行該代碼來啟動(dòng)子應(yīng)用。在執(zhí)行代碼時(shí),模塊加載器會(huì)創(chuàng)建一個(gè)獨(dú)立的運(yùn)行環(huán)境,用來隔離不同子應(yīng)用之間的代碼和數(shù)據(jù)。該運(yùn)行環(huán)境基于瀏覽器提供的 iframe 技術(shù),從而實(shí)現(xiàn)了代碼和數(shù)據(jù)的互相隔離。同時(shí),該運(yùn)行環(huán)境還支持在子應(yīng)用中使用全局變量和函數(shù),從而實(shí)現(xiàn)了一定的共享性。
動(dòng)態(tài)加載和卸載子應(yīng)用:模塊加載器還支持在運(yùn)行時(shí)動(dòng)態(tài)加載和卸載子應(yīng)用。在加載子應(yīng)用時(shí),模塊加載器會(huì)創(chuàng)建一個(gè)獨(dú)立的 iframe,用來隔離該子應(yīng)用的代碼和數(shù)據(jù)。在卸載子應(yīng)用時(shí),模塊加載器會(huì)銷毀該 iframe,并清除該子應(yīng)用的代碼和數(shù)據(jù),從而釋放內(nèi)存和資源。
沙箱
在微前端框架 qiankun 中,沙箱是實(shí)現(xiàn)子應(yīng)用之間隔離的核心組件之一,它能夠在不同技術(shù)棧之間進(jìn)行隔離,從而確保每個(gè)子應(yīng)用的運(yùn)行環(huán)境都是獨(dú)立的。沙箱的設(shè)計(jì)和實(shí)現(xiàn)主要包括以下幾個(gè)方面:
運(yùn)行環(huán)境的隔離:沙箱首先需要在運(yùn)行環(huán)境層面進(jìn)行隔離,確保每個(gè)子應(yīng)用運(yùn)行在自己的沙箱中。為此,沙箱會(huì)利用瀏覽器提供的 iframe 技術(shù)創(chuàng)建獨(dú)立的運(yùn)行環(huán)境,從而實(shí)現(xiàn)每個(gè)子應(yīng)用的隔離。
代碼隔離:沙箱還需要確保每個(gè)子應(yīng)用的代碼之間互相隔離,從而防止代碼之間的沖突。為此,沙箱會(huì)使用 JavaScript 的沙箱技術(shù),通過運(yùn)行子應(yīng)用代碼的方式來實(shí)現(xiàn)隔離。具體來說,沙箱會(huì)創(chuàng)建一個(gè) JavaScript 上下文環(huán)境,將子應(yīng)用的代碼加載進(jìn)去,并運(yùn)行該代碼,從而實(shí)現(xiàn)代碼的隔離。
DOM 隔離:沙箱還需要確保每個(gè)子應(yīng)用之間的 DOM 結(jié)構(gòu)互相隔離,從而防止樣式和腳本之間的沖突。為此,沙箱會(huì)使用 Shadow DOM 技術(shù),將子應(yīng)用的 DOM 結(jié)構(gòu)封裝在一個(gè) Shadow DOM 中,從而確保 DOM 的隔離。
全局變量隔離:沙箱還需要確保每個(gè)子應(yīng)用之間的全局變量互相隔離,從而防止變量的沖突。為此,沙箱會(huì)使用 Proxy 技術(shù),將子應(yīng)用的全局變量封裝在一個(gè) Proxy 中,并攔截該 Proxy 的讀寫操作,從而實(shí)現(xiàn)全局變量的隔離。
通過以上幾個(gè)方面的設(shè)計(jì)和實(shí)現(xiàn),沙箱能夠在不同技術(shù)棧之間進(jìn)行隔離,從而確保每個(gè)子應(yīng)用的運(yùn)行環(huán)境都是獨(dú)立的,并且代碼、DOM 和全局變量之間不會(huì)相互干擾。這為微前端框架 qiankun 的技術(shù)棧無關(guān)特性提供了堅(jiān)實(shí)的保障。
