微前端-乾坤《》

微前端?

?一個應用,當不斷迭代的時候,功能會越來越多,代碼量隨著也會變得越來越大。進而代碼之間的耦合性會變高,這樣導致開發和維護很糟心,動一發而牽全身。于是有了微前端來解這個問題,按功能可以將這個應用拆分成多個項目,每個項目都是獨立的倉庫,獨立的部署,然后利用微前端再組合成在一起。
較大的前端應用拆分為若干個可以獨立交付的前端應用。每個應用大小及復雜度相對可控。能降低應用之間的耦合度,獨立開發,獨立運行,獨立部署,提升每個團隊的自治能力。

實現原理?

?乾坤是基于single-spa框架的,而single-spa是一個將多個單頁面應用聚合為一個整體應用的 JavaScript 微前端框架,而乾坤在single-spa的基礎上主要做了資源的加載和應用之間的隔離。

  • 下面是single-spa的使用示例。通過registerApplication來注冊子應用,然后當頁面的路由與activeWhen首次相匹配時,就會觸發app函數的執行。這個函數里面返回一些生命周期,在這些生命周期里做一些渲染。
  • ·
    import * as singleSpa from 'single-spa';//注冊應用
    singleSpa.registerApplication({name: 'app1',//應用激活路由條件activeWhen: '/app1',app(){const domEl = document.getElementById('#container')return {//首次掛載時執行bootstrap(){},//掛載時執行mount(){domEl.innerHTML = 'App 1 is mounted!'}, //卸載時執行unmount(){domEl.innerHTML = ''}}}
    })
    singleSpa.registerApplication({name: 'app2',activeWhen: '/app2',app(){const domEl = document.getElementById('#container')return {bootstrap(){},mount(){domEl.innerHTML = 'App 2 is mounted!'}, unmount(){domEl.innerHTML = ''}}}
    })singleSpa.start();

    下面是乾坤的使用示例。在single-spa中配置的是函數,而在乾坤中配置的是文件地址。

  • import {registerMicroApps, start} from 'qiankun';registerMicroApps([{name: 'app1',entry: {scripts: ['/app1.js'],styles:['/app1.css']},container: '#container',activeRule: '/app1',},{name: 'app2',entry: {scripts: ['/app2.js']},container: '#container',activeRule: '/app2',},]);start();

解決跨域(主應用間路由跳轉,微應用如何設置跨域訪問,各生命周期鉤子如何執行)

header:{Access-Control-Allow-Origin:'*"}

?

沙盒?

沙盒主要作用就是隔離微應用之間的腳本和樣式影響,需要處理style、link、script類型的標簽。對于處理的時機第一個是在首次加載的時候,第二個是在微應用運行中。在運行中的處理方案就是乾坤重寫了下面這些原生的方法,這樣就可以監聽到新添加的節點,然后對style、link、script標簽進行處理。

if (//原始方法未被替換HTMLHeadElement.prototype.appendChild === rawHeadAppendChild &&HTMLBodyElement.prototype.appendChild === rawBodyAppendChild &&HTMLHeadElement.prototype.insertBefore === rawHeadInsertBefore
) {//替換原始方法HTMLHeadElement.prototype.appendChild = getOverwrittenAppendChildOrInsertBefore({rawDOMAppendOrInsertBefore: rawHeadAppendChild,containerConfigGetter,isInvokedByMicroApp,}) as typeof rawHeadAppendChild;...
}

?

腳本隔離(一種是快照拷貝的方式,一個是基于proxy的方式)?

腳本隔離的方式主要有兩種,一種是快照拷貝的方式,一個是基于proxy的方式。乾坤會根據當前環境是否支持proxy來決定用那種方式。

  1. 快照方式

下面是乾坤中關于快照隔離的代碼。在創建微應用的時候會實例化一個沙盒對象,它有兩個方法,active是在激活微應用的時候執行,而inactive是在離開微應用的時候執行。

整體的思路是在激活微應用時將當前的window對象拷貝存起來,然后從modifyPropsMap中恢復這個微應用上次修改的屬性到window中。在離開微應用時會與原有的window對象做對比,將有修改的屬性保存起來,以便再次進入這個微應用時進行數據恢復,然后把有修改的屬性值恢復到以前的狀態。

?

//遍歷對象屬性,用callbackFn回調
function iter(obj: typeof window, callbackFn: (prop: any) => void) {for (const prop in obj) {if (obj.hasOwnProperty(prop) {callbackFn(prop);}}
} 
class SnapshotSandbox implements SandBox {active() {// 記錄當前快照this.windowSnapshot = {} as Window;iter(window, (prop) => {this.windowSnapshot[prop] = window[prop];});// 恢復之前的變更Object.keys(this.modifyPropsMap).forEach((p: any) => {window[p] = this.modifyPropsMap[p];});}inactive() {this.modifyPropsMap = {};iter(window, (prop) => {if (window[prop] !== this.windowSnapshot[prop]) {// 保存變更this.modifyPropsMap[prop] = window[prop];// 恢復到以前的狀態window[prop] = this.windowSnapshot[prop];}});}
}

2.proxy方式

乾坤中關于proxy的隔離方式有兩種,我們以最優的方案分析。下面中的代碼省略了很多,只講其中的原理。

微應用中的script內容都會加with(global)來執行,這里global是全局對象,如果是proxy的隔離方式那么他就是下面新創建的proxy對象。我們知道with可以改變里面代碼的作用域,也就是我們的微應用全局對象會變成下面的這個proxy。當設置屬性的時候會設置到proxy對象里,在讀取屬性時先從proxy里找,沒找到再從原始的window中找。也就是你在微應用里修改全局對象的屬性時不會在window中修改,而是在proxy對象中修改。因為不會破壞window對象,這樣就會隔離各個應用之間的數據影響。

?

class implements SandBox {constructor(name: string) {const rawWindow = window;const proxy = new Proxy(fakeWindow, {set: (target: FakeWindow, p: PropertyKey, value: any): boolean => {//修改對象直接保存到proxy對象中target[p] = value;},get(target: FakeWindow, p: PropertyKey): any {// 從proxy對象中獲取,獲取不到從fakeWindow中獲取const value = p in target? (target as any)[p]: (rawWindow as any)[p];return value;}})}
}

樣式隔離?

默認情況下沙箱可以確保單實例場景子應用之間的樣式隔離(切換子應用時會卸載添加的樣式標簽),但是無法確保主應用跟子應用、或者多實例場景的子應用樣式隔離,需要手動增加配置參數才能激活下面的隔離。

  1. 域隔離

為每個css規則添加特定的前綴來起到隔離的作用,例如微應用中的樣式是p{color:#000},處理后為.app1 p {color:#000} 。

  • 創建一個臨時的style節點用來后續處理
  • 調用process來處理style規則
  • 通過style的sheet屬性來獲取一條條規則
  • 然后調用ruleStyle進行轉化,轉化是通過正則進行匹配然后替換
  • 最后把轉化后的內容替換到原有的style節點中

?

class ScopedCSS {  constructor() {//創建一個臨時style節點,用來處理樣式this.swapNode = document.createElement('style');rawDocumentBodyAppend.call(document.body, styleNode);}process(styleNode: HTMLStyleElement, prefix: string = '') {//style節點內容不為空if (styleNode.textContent !== '') {//獲取內部的樣式規則this.swapNode.appendChild(styleNode.textContent);const sheet = this.swapNode.sheet as any;//獲取替換后的cssconst css = this.ruleStyle(sheet, prefix);//應用替換后的cssstyleNode.textContent = css;}}private ruleStyle(rule: CSSStyleRule, prefix: string) {const rootSelectorRE = /((?:[^\w\-.#]|^)(body|html|:root))/gm;const selector = rule.selectorText.trim();let { cssText } = rule;//\s\S 匹配所有   這里可以匹配到如 body{cssText = cssText.replace(/^[\s\S]+{/, (selectors) =>// div,span{}  逗號拆分處理selectors.replace(/(^|,\n?)([^,]+)/g, (item, p, s) => {// handle div,body,span { ... }if (rootSelectorRE.test(item)) {return item.replace(rootSelectorRE, (m) => {const whitePrevChars = [',', '('];//處理前面有, (if (m && whitePrevChars.includes(m[0])) {return `${m[0]}${prefix}`;}//直接返回prefixreturn prefix;});}//p 匹配到逗號 , s為 span{     后面這里會去掉空白return `${p}${prefix} ${s.replace(/^ */, '')}`;}),);return cssText;}
}

遇到過哪些問題?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/715616.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/715616.shtml
英文地址,請注明出處:http://en.pswp.cn/news/715616.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

day02-JavaScript-Vue

文章目錄 1 JavaScript1.1 介紹 1.2 引入方式1.3 基礎語法1.3.1 書寫語法1.3.2 變量1.3.3 數據類型和運算符 1.4 函數1.4.1 第一種定義格式1.4.2 第二種定義格式 1.5 JavaScript對象1.5.1 基本對象1.5.1.1 Array對象語法格式特點屬性和方法 1.5.1.2 String對象語法格式屬性和方…

17.來自Sora的奪舍妄想——享元模式詳解

OpenAI 的 Sora 模型面世之后,可以說人類抵御AI的最后陣地也淪陷了。 在此之前,人們面對AI交互式對話,AI制圖,AI建模之類的奇跡時,還可以略微放肆的說:“的確很神奇,這畢竟還是比人類世界低了一…

Redis基本知識

一、什么是Redis Redis是一種基于內存的數據庫,對數據的讀寫操作都是在內存中完成,因此讀寫速度非常快,用于存儲鍵值對、緩存、消息隊列、分布式鎖等。 二、Redis和mencached的區別 相同:都是基于內存的數據庫,讀寫都…

2024年騰訊云部署幻獸帕魯服務器,如何選擇合適的服務器配置套餐暢玩游戲?

選擇合適的服務器配置套餐以暢玩《幻獸帕魯》游戲,首先需要考慮的是玩家數量和對服務器性能的需求。根據騰訊云提供的配置推薦,對于4到8人的玩家,推薦配置為4核16G12M;而10到20人的玩家則建議選擇8核32G22M配置。這是因為《幻獸帕…

小程序頁面指定區域局部滾動,做上拉和觸底刷新

業務需求:在頁面某個固定區域滑動 思路:滑動高度 頁面高度 - 自定義導航高度(不是自己自定義的導航可以省略)- 按鈕高度 - 單詞數高度 實現 : 1.數據展示區內使用scroll-view,設置y軸滾動(…

swoole

php是單線程。php是靠多進程來處理任務,任何后端語言都可以采用多進程處理方式。如我們常用的php-fpm進程管理器。線程與協程,大小的關系是進程>線程>協程,而我們所說的swoole讓php實現了多線程,其實在這里來說,就是好比讓php創建了多個進程,每個進程執行一條…

初階數據結構:二叉樹

目錄 1. 樹的相關概念1.1 簡述:樹1.2 樹的概念補充 2. 二叉樹2.1 二叉樹的概念2.2 二叉樹的性質2.3 二叉樹的存儲結構與堆2.3.1 存儲結構2.3.2 堆的概念2.3.3 堆的實現2.3.3.1 堆的向上調整法2.3.3.2 堆的向下調整算法2.3.3.3 堆的實現 1. 樹的相關概念 1.1 簡述&a…

域名及地址正確外,若依后臺無法正常加載頁面和退出報404問題

寫小程序退出的時候,另外寫了一個自定義退出處理類,里面的響應瀏覽器的代碼每次都走。因為原來也有個退出處理類,所以先后走了2次,因為就出現了問題。 LogoutSuccessHandlerImpl類里的: ServletUtils.renderString(r…

【C++ AVL樹】

文章目錄 AVL樹AVL樹的概念AVL樹節點的定義AVL樹的插入AVL樹的旋轉右單旋左單旋左右雙旋右左雙旋 代碼實現 總結 AVL樹 AVL樹的概念 二叉搜索樹在順序有序或接近有序的情況下,而插入搜索樹將退化為單叉樹,此時查找的時間復雜度為O(n),效率低…

鴻蒙Harmony應用開發—ArkTS聲明式開發(通用屬性:顏色漸變)

設置組件的顏色漸變效果。 說明: 從API Version 7開始支持。后續版本如有新增內容,則采用上角標單獨標記該內容的起始版本。 linearGradient linearGradient(value: { angle?: number | string; direction?: GradientDirection; colors: Array; repea…

mamba-ssm安裝building wheel卡著不動后error...避坑解決方法

文章目錄 方法1、下載whl文件到本地后pip install安裝成功后驗證: 方法2、拉取Docker鏡像 對于項目中用到MambaIR的小伙伴,需要pip安裝 causal_conv1d和 mamba-ssm兩個包及其依賴: torch packing transformersMambaIR-Github主頁&#xff0…

【C++】vector的使用及其模擬實現

這里寫目錄標題 一、vector的介紹及使用1. vector的介紹2. 構造函數3. 遍歷方式4. 容量操作及空間增長問題5. 增刪查改6. vector二維數組 二、vector的模擬實現1. 構造函數2. 迭代器和基本接口3. reserve和resize4. push_back和pop_back5. insert和erase5. 迭代器失效問題5. 淺…

【Java】基礎算法練習題

個人簡介:Java領域新星創作者;阿里云技術博主、星級博主、專家博主;正在Java學習的路上摸爬滾打,記錄學習的過程~ 個人主頁:.29.的博客 學習社區:進去逛一逛~ 目錄 基礎算法練習題🚀1. 兩數之和…

Django 管網項目 三

Django 官網文檔 ??Writing your first Django app, part 2 | Django documentation | Django 本文內容涉及創建視圖 View,路由,和模版。并對內容進行渲染。 創建視圖 在我們的投票應用中,我們需要下列幾個視圖: 問題索引頁—…

ChatGPT支持下的PyTorch機器學習與深度學習技術應用

近年來,隨著AlphaGo、無人駕駛汽車、醫學影像智慧輔助診療、ImageNet競賽等熱點事件的發生,人工智能迎來了新一輪的發展浪潮。尤其是深度學習技術,在許多行業都取得了顛覆性的成果。另外,近年來,Pytorch深度學習框架受…

相關知識1111

一、 店鋪編號和相關負責人 1、天貓兄弟、錦格 京東凡越 福林哥 如萍姐 2、京東錦格 天貓凡越 林森 雷佳華 3、天貓從簡 京東從簡 孔哥 4、抖音錦格 拼多多凡越 鴻哥 不知道哪個店鋪編號:0 二、天貓京東聊天界面快捷搜索商品 1、 天貓只能根據標題搜索 2、京東是…

神經網絡之萬能定理python-pytorch實現,可以擬合任意曲線

神經網絡之萬能定理python-pytorch實現,可以擬合任意曲線 博主,這幾天一直在做這個曲線擬合的實驗,講道理,網上可能也有很多這方面的資料,但是博主其實試了很多,效果只能對一般的曲線還行,稍微…

java之抽象類

什么是抽象類? 抽象就是不能具體化,不能實例化 作為父類,讓子類去實現 abstract修飾類就是抽象類 abstract修飾方法就是抽象方法修飾符 abstract class 類名{修飾符 abstract 返回值類型 方法名(形參列表); }public abstract class A {//不…

CTFHUB--文件包含漏洞--RCE

文件包含漏洞 文件包含漏洞也是一種注入型漏洞,其本質就是輸入一段用戶能夠控制的腳本或者代碼,并讓服務端執行。有時候由于網站功能需求,會讓前端用戶選擇要包含的文件,而開發人員又沒有對要包含的文件進行安全考慮,…

CSS【詳解】居中對齊 (水平居中 vs 垂直居中)

水平居中 內部塊級元素的寬度要小于容器(父元素) 方案一&#xff1a;文本居中對齊&#xff08;內聯元素&#xff09; 限制條件&#xff1a;僅用于內聯元素 display:inline 和 display: inline-block; 給容器添加樣式 text-align:center<!DOCTYPE html> <html lang&q…