微前端學習(qiankun、singleSpa)
一、微前端的優勢
-
什么是微前端
-
微前端是一種多個團隊通過獨立發布功能的方式來共同構建現代化 web 應用的技術手段及方法策略
幾個核心價值:技術堆疊無關,獨立開發、獨立部署,增量升級,獨立運行時
-
-
特點
- 基于single-spa封裝,提供了更加開箱即用的 API,
- HTML Entry 接入方式,讓你接入微應用像使用 iframe 一樣簡單,
- 樣式隔離,確保微應用之間樣式互相不干擾,
- JS 沙箱,確保微應用之間 全域變數/事件 不沖突,
- 資源預加載,在瀏覽器空閑時間預加載未打開的微應用資源,加速微應用打開速度,
- umi 插件,提供了 @umijs/plugin-qiankun 供 umi 應用一鍵切換成微前端架構系統,
二、知識點擴展
-
樣式的隔離:
-
實作原理:影子根attachShadow() 開辟一個封閉的陰影盒子,避免其他樣式的參考
-
attachShadow學習:https://developer.mozilla.org/zh-CN/docs/Web/API/Element/attachShadow
-
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>樣式隔離演示</title> </head> <body> <div> <p>fur</p> <div id="shadow"></div> </div> <script> let shadow = document.getElementById('shadow') //可以省略 let shadowDOM = shadow.attachShadow({ mode: 'closed' }); //外界無法訪間closed let pElm = document.createElement('p'); pElm.innerHTML = "hello fur" let styleElm = document.createElement("style"); styleElm.textContent = `p{color:red}` // 添加樣式 shadowDOM.appendChild(styleElm) shadowDOM.appendChild(pElm) document.body.appendChild(pElm) // 添加到陰影外面,就無法控制其樣式 </script> </body> </html>
-
-
快照沙箱
-
作用:隔離js,防止全域污染
-
實作原理:默認初始化先回圈遍歷保存一份以前的資料,切換inactive(失活狀態下),先保存不同的資料(方便以后的資料恢復),然后恢復為以前的資料;切換active(激活狀態),把資料恢復為剛剛保存的不同的資料,
-
j簡單代碼示例:(淺拷貝記錄資料)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>快照沙箱實作示例</title> </head> <body> </body> <script> //快照沙箱dome class SnapshotSandbox { constructor() { this.proxy = window; // window屬性 this.modifyPropsMap = {}; //記錄在window上的修改 this.active(); } active() { //激活 this.windowSnapshot = {}; //拍照:保存全部window屬性 for (const prop in window) { if (window.hasOwnProperty(prop)) { this.windowSnapshot[prop] = window[prop]; } } // 激活:賦值原來的數值 Object.keys(this.modifyPropsMap).forEach(p => { window[p] = this.modifyPropsMap[p] }) } inactive() {//失活 for (const prop in window) { if (window.hasOwnProperty(prop)) { if (this.windowSnapshot[prop] !== window[prop]) { this.modifyPropsMap[prop] = window[prop]; ///保存變化 window[prop] = this.windowSnapshot[prop] //失活:變回原來 } } } } } let sandbox = new SnapshotSandbox(); ((window) => { // 1、實體化sandbox時默認激活了一次 window.a = 1 window.b = 2 console.log(window.a) //1 sandbox.inactive() //失活 console.log(window.a) //undefined sandbox.active() //激活 console.log(window.a) //1 })(sandbox.proxy); //sandbox.proxy就是window </script> </html>
-
-
js沙箱
-
作用:隔離js,防止全域污染
-
實作原理:利用**new Proxy()**包裝代理不同的windon物件,代理物件之間會不干擾
-
-
Proxy()學習Script/Reference/Global_Objects/Proxy
-
代碼示例:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>proxy多應用沙箱實作示例(js沙箱)</title> </head> <body> </body> <script> //proxy的demo class ProxySandbox { constructor() { const rawWindow = window; const fakeWindow = {} const proxy = new Proxy(fakeWindow, { set(target, p, value) { target[p] = value; return true }, get(target, p) { return target[p] || rawWindow[p]; } }) this.proxy = proxy } } /** * 原理: * 1、利用Proxy實體化不同的window物件 * 2、不同的對之間互不干預, * */ let sandbox1 = new ProxySandbox(); let sandbox2 = new ProxySandbox(); window.a = 1; ((window) => { window.a = 'hello'; console.log(window.a) })(sandbox1.proxy); ((window) => { window.a = 'world'; console.log(window.a) })(sandbox2.proxy); </script> </html>
三、實作微前端的方法
-
iframe
- 特點:iframe 最大的特性就是提供了瀏覽器原生的硬隔離方案,不論是樣式隔離、js 隔離這類問題統統都能被完美解決,但他的最大問題也在于他的隔離性無法被突破,導致應用間背景關系無法被共享,
- 缺點:
- url 不同步,瀏覽器重繪 iframe url 狀態丟失、后退前進按鈕無法使用,
- UI 不同步,DOM 結構不共享,想象一下螢屏右下角 1/4 的 iframe 里來一個帶遮罩層的彈框,同時我們要求這個彈框要瀏覽器居中顯示,還要瀏覽器 resize 時自動居中…
- 全域背景關系完全隔離,記憶體變數不共享,iframe 內外系統的通信、資料同步等需求,主應用的 cookie 要透傳到根域名都不同的子應用中實作免登效果,
- 慢,每次子應用進入都是一次瀏覽器背景關系重建、資源重新加載的程序,
-
singleSpa
-
配置實作:
-
主應用配置
-
下載依賴:
npm i single-spa -savejs -
main.js 中配置
import Vue from 'vue' import App from './App.vue' import router from './router' import store from './store' import {registerApplication,start} from "single-spa" Vue.config.productionTip = false // 封裝:script標簽動態加載 async function loadScript(url){ return new Promise((resolve,reject)=>{ let script = document.createElement("script"); script.src = url; script.onload = resolve; script.onerror = reject; document.head.appendChild(script); }) } /** * singlespa 缺陷:不夠靈活,不能動態加載js檔案 * 樣式不隔離,沒有js沙箱機制 */ registerApplication("myApp", async ()=>{ console.log("加載子應用中..."); await loadScript("http://localhost:10000/js/chunk-vendors.js"); await loadScript("http://localhost:10000/js/app.js"); return window.sigleVue }, location=>location.pathname.startsWith("/vue"), // 匹配加載路由 ); // 開啟應用 start(); new Vue({ router, store, render: h => h(App) }).$mount('#app') -
掛載應用
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-hI6y7kKl-1603706137263)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20201026165342047.pnghttps://img-blog.csdnimg.cn/20201026180131205.png alt="在這里插入圖片描述" />
五、qiankun 微前端通訊方式
- 未完成,敬請期待,,,,
-
-
-
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/194980.html
標籤:其他
下一篇:記一次分布式鎖-基于資料庫
