柚子快報邀請碼778899分享:前端框架 常見微前端方案
轉(zhuǎn)載請注明出處,點擊此處 查看更多精彩內(nèi)容
iframe
iframe 是 HTML 的內(nèi)聯(lián)框架元素,表示嵌套的 Browsing Context,它能夠?qū)⒘硪粋€ HTML 頁面嵌入到當前頁面中,每個嵌入的 Browsing Context 都有自己的會話歷史記錄和 DOM 樹。
每個瀏覽上下文都擁有完整的文檔環(huán)境,因此頁面上每個 iframe 都需要增加內(nèi)存和其它計算資源,雖然理論上來說能夠在代碼中寫出來無限多的 iframe,但是這么做可能會導致某些性能問題。
優(yōu)點
Web 應用隔離的非常完美,無論是 JavaScript、CSS、DOM 都完全隔離開來。非常簡單,使用沒有任何心智負擔。
缺點
DOM 結(jié)構(gòu)不共享,彈窗只能在 iframe 內(nèi)部展示,無法覆蓋全局。路由狀態(tài)丟失,刷新頁面會導致 iframe 的 url 狀態(tài)丟失、后退前進按鈕無法使用。性能差,每次子應用進入都是一次瀏覽器上下文重建、資源重新加載的過程。應用之間通信困難,全局上下文完全隔離,內(nèi)存變量不共享,無法訪問非同源的 window 對象的幾乎所有屬性,跨域通信僅可通過 window.postMessage() 來實現(xiàn)。
路由轉(zhuǎn)發(fā)
路由分發(fā)式微前端,即通過路由將不同的業(yè)務(wù)分發(fā)到不同的獨立前端應用上。最常用的方案是通過 HTTP 服務(wù)的反向代理(如 Nginx)將不同頁面的請求分發(fā)到不同的服務(wù)上。
優(yōu)點
實現(xiàn)簡單。維護、開發(fā)成本低。不需要對現(xiàn)有應用進行改造。
缺點
用戶體驗不好,每次切換應用時,瀏覽器都需要重新加載頁面。子應用之間的通信比較困難。多個子應用無法并存。子應用切換時需要重新登錄。
動態(tài)加載模塊
創(chuàng)建一個基座應用,允許子應用單獨部署。為了實現(xiàn)這一點,創(chuàng)建一個 manifest 文件,記錄上線的子應用及版本信息,當子應用部署更新時修改 manifest 文件,基座應用通過 manifest 檢查更新子應用資源。
改變每個子應用加載的 JavaScript 文件有很多的方法:
Web 服務(wù)器:在你的 Web 服務(wù)器為每個子應用的正確版本創(chuàng)建一個動態(tài)腳本。使用模塊加載 例如 SystemJS 可以在瀏覽器通過動態(tài) urls 下載并執(zhí)行 JavaScript 代碼。
npm
每個子應用在一個單獨的代碼倉庫中,每次更新時發(fā)布一個新版本到 npm,創(chuàng)建一個基座應用,通過 npm 安裝每個子應用。
優(yōu)點
npm 安裝對于開發(fā)中更熟悉,易于搭建。
缺點
子應用發(fā)生變更時,基座應用需要重新安裝、重新構(gòu)建和重新部署。無法動態(tài)安裝、卸載子應用。
Web Component
Web Component 是一套不同的技術(shù),允許你創(chuàng)建可重用的定制元素(它們的功能封裝在你的代碼之外)并且在你的 Web 應用中使用它們。
Web Components 由三項主要技術(shù)組成,它們可以一起使用來創(chuàng)建封裝功能的定制元素,可以在你喜歡的任何地方重用,不必擔心代碼沖突。
Custom Element(自定義元素) 一組 JavaScript API,允許您定義 Custom Elements 及其行為,然后可以在您的用戶界面中按照需要使用它們。Shadow DOM(影子 DOM) 一組 JavaScript API,用于將封裝的“影子”DOM 樹附加到元素(與主文檔 DOM 分開呈現(xiàn))并控制其關(guān)聯(lián)的功能。通過這種方式,您可以保持元素的功能私有,這樣它們就可以被腳本化和樣式化,而不用擔心與文檔的其他部分發(fā)生沖突。HTML Template(HTML 模板) 和
基于 Web Component 的 Shadow Dom 能力,我們也可以實現(xiàn)微前端,將多個子應用聚合起來。
const shadow = document.querySelector('#hostElement').attachShadow({mode: 'open'});
// url 為應用的地址,基于 fetch,我們可以獲取到應用的 html 模板,添加到指定節(jié)點下
fetch(url).then(res => {
shadow.innerHTML = res
});
優(yōu)點
實現(xiàn)簡單。完全技術(shù)棧無關(guān)。不需要對現(xiàn)有應用進行改造。CSS 和 JavaScript 天然隔離,互不干擾。
缺點
沒有統(tǒng)一的 Web Component 規(guī)范。瀏覽器實現(xiàn)不一致。Web 組件存在向后不兼容的版本問題。開發(fā)成本較高。
EMP
EMP 基于 Webpack5 的 Module Federation 實現(xiàn),用一個詞概括,就是“去中心化”,在 EMP 的方案中不需要中心化的基座,每一個微前端應用都可以通過遠程調(diào)用的方式引入共享模塊。
優(yōu)點
Webpack5 Module Federation 可以保證所有子應用依賴解耦。模塊遠程 TypeScript 支持。應用間去中心化的調(diào)用、共享模塊。
缺點
對 Webpack 強依賴,老舊項目不友好。沒有有效的 CSS 沙箱和 JavaScript 沙箱,需要靠用戶自覺。主、子應用的路由可能發(fā)生沖突。子應用?;睢⒍鄳眉せ顭o法實現(xiàn)。
single-spa / qiankun
single-spa 是一個目前主流的微前端技術(shù)方案。
single-spa 從現(xiàn)代框架組件生命周期中獲得靈感,將生命周期應用于整個應用程序,其主要實現(xiàn)思路:
預先注冊子應用(激活路由、子應用資源、生命周期函數(shù))。監(jiān)聽路由的變化,匹配到了激活的路由則加載子應用資源,順序調(diào)用生命周期函數(shù)并最終渲染到容器。
single-spa 未解決子應用加載、應用隔離、子應用通信等問題。
qiankun 微前端架構(gòu)則進一步對 single-spa 方案進行完善,主要的完善點:
子應用資源由 JavaScript 列表修改進為一個 url,大大減輕注冊子應用的復雜度。增加資源預加載能力,預先緩存子應用的 HTML、JavaScript、CSS 資源,加快子應用的打開速度。實現(xiàn)應用隔離,完成 JavaScript 隔離方案 (window 工廠) 和 CSS 隔離方案 (類 Vue 的 scoped)。提供了 @umijs/plugin-qiankun 供 umi 應用一鍵切換成微前端架構(gòu)系統(tǒng)。
優(yōu)點
監(jiān)聽路由自動的加載、卸載當前路由對應的子應用。路由保持,瀏覽器刷新、前進、后退,都可以作用到子應用。應用間通信簡單,全局注入。完備的沙箱方案,JavaScript 沙箱做了 SnapshotSandbox、LegacySandbox、ProxySandbox 三套漸進增強方案,CSS 沙箱做了兩套 strictStyleIsolation、experimentalStyleIsolation 兩套適用不同場景的方案。
缺點
改造成本較大,從 Webpack、代碼、路由等等都要做一系列的適配?;诼酚善ヅ?,無法同時激活多個子應用,也不支持子應用保活。CSS 沙箱無法絕對的隔離,JavaScript 沙箱在某些場景下執(zhí)行性能下降嚴重。無法支持 Vite 等 ESM 腳本運行。
無界(wujie)
無界利用 iframe 的沙箱機制,將子應用的 JavaScript 注入到基座應用同域的 iframe 中運行,并采用 Web Component 實現(xiàn)頁面的樣式隔離。
應用加載機制和 JavaScript 沙箱機制 將子應用的 JavaScript 注入主應用同域的 iframe 中運行,iframe 是一個原生的 window 沙箱,內(nèi)部有完整的 history 和 location 接口,子應用實例運行在 iframe 中,路由主應用解耦,可以直接在業(yè)務(wù)組件里面啟動應用。路由同步機制 劫持 iframe 的 history.pushState 和 history.replaceState,就可以將子應用的 url 同步到主應用的 query 參數(shù)上,當刷新瀏覽器初始化 iframe 時,讀回子應用的 url 并使用 iframe 的 history.replaceState 進行同步。iframe 連接機制和 CSS 沙箱機制 無界采用 Web Component 來實現(xiàn)頁面的樣式隔離,無界會創(chuàng)建一個 wujie 自定義元素,然后將子應用的完整結(jié)構(gòu)渲染在內(nèi)部。子應用的實例在 iframe 內(nèi)運行,DOM 在主應用容器下的 Web Component 內(nèi),通過代理 iframe 的 document 到 Web Component,可以實現(xiàn)兩者的互聯(lián)。通信機制 承載子應用的 iframe 和主應用是同域的,所以主、子應用天然就可以很好的進行通信,無界提供三種通信方式。
props 注入機制,子應用通過 $wujie.props 可以輕松拿到主應用注入的數(shù)據(jù)。子應用 iframe 沙箱和主應用同源,子應用可以直接通過 window.parent 和主應用通信。無界提供了 EventBus 實例,注入到主應用和子應用,所有的應用可以去中心化的進行通信。
優(yōu)點
多應用同時激活在線 框架具備同時激活多應用,并保持這些應用路由同步的能力。組件式的使用方式 無需注冊,更無需路由適配,在組件內(nèi)使用,跟隨組件裝載、卸載。應用級別的 keep-alive 子應用開啟?;钅J胶螅瑧冒l(fā)生切換時整個子應用的狀態(tài)可以保存下來不丟失,結(jié)合預執(zhí)行模式可以獲得類似 SSR 的打開體驗。純凈無污染
無界利用 iframe 和 Web Component 來搭建天然的 JavaScript 隔離沙箱和 CSS 隔離沙箱。利用 iframe 的 history 和主應用的 history 在同一個 top-level Browsing Context 來搭建天然的路由同步機制。副作用局限在沙箱內(nèi)部,子應用切換無需任何清理工作,沒有額外的切換成本。 性能和體積兼具
子應用執(zhí)行性能和原生一致,子應用實例運行在 iframe 的 window 上下文中,避免 with(proxyWindow){code} 這樣指定代碼執(zhí)行上下文導致的性能下降,但是多了實例化 iframe 的一次性的開銷,可以通過 preload 提前實例化。體積比較輕量,借助 iframe 和 Web Component 來實現(xiàn)沙箱,有效的減小了代碼量。 開箱即用 不管是樣式的兼容、路由的處理、彈窗的處理、熱更新的加載,子應用完成接入即可開箱即用無需額外處理,應用接入成本也極低。子應用運行在 iframe 中,原生支持 ESM 的腳本。
缺點
iframe 的一些坑尚未解決,如路由回退問題。
micro-app
micro-app 借鑒了 Web Component 的思想,通過 Custom Element 結(jié)合自定義的 Shadow Dom,將微前端封裝成一個類 Web Component 組件,從而實現(xiàn)微前端的組件化渲染。并且由于自定義 Shadow Dom 的隔離特性,micro-app 不需要像 single-spa 和 qiankun 一樣要求子應用修改渲染邏輯并暴露出方法,也不需要修改 Webpack 配置,在基座應用中嵌入一行代碼即可渲染一個微前端應用,是目前市面上接入微前端成本最低的方案。
優(yōu)點
零依賴 micro-app 沒有任何依賴,這賦予它小巧的體積和更高的擴展性。使用簡單 我們將所有功能都封裝到一個類 Web Component 組件中,從而實現(xiàn)在基座應用中嵌入一行代碼即可渲染一個微前端應用。同時 micro-app 還提供了 JavaScript 沙箱、樣式隔離、元素隔離、預加載、數(shù)據(jù)通信、靜態(tài)資源補全等一系列完善的功能。兼容所有框架 為了保證各個業(yè)務(wù)之間獨立開發(fā)、獨立部署的能力,micro-app 做了諸多兼容,在任何技術(shù)框架中都可以正常運行。
缺點
多應用激活后無法保持子應用的路由狀態(tài),刷新后全部丟失。對于不支持 Web Component 的瀏覽器沒有做降級處理。支持 Vite 運行,但必須使用 plugin 改造子應用,且 JavaScript 代碼沒辦法做沙箱隔離。較長時間未更新,穩(wěn)定版最近一次發(fā)版(v0.8.10)時間是 2022.08.19,測試版最近一次發(fā)版(v1.0.0-alpha.10)時間是 2022.10.11。
柚子快報邀請碼778899分享:前端框架 常見微前端方案
推薦鏈接
本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點和立場。
轉(zhuǎn)載請注明,如有侵權(quán),聯(lián)系刪除。