乾坤微前端js沙箱机制

devtools/2024/12/23 2:00:19/

1 快照沙箱

  1. modifyPropsMap对象存储子应用的属性; windowSnapshot对象存储微应用未加载时的window对象属性;
  2. 进入微应用,利用windowSnapshot对象存储window对象的属性; 并将window对象的属性替换为modifyPropsMap对象的属性;
  3. 离开微应用:modifyPropsMap对象属性同步window对象属性; window对象属性还原为 windowSnapshot对象属性;

缺点:

  • 不支持多个微应用同时处于运行状态;
  • 遍历window对象上的所有属性,性能差;
    优点:
  • 适用于所有浏览器;
javascript">class SanapshotSandbox {windowSnapshot = {};modifyPropsMap = {};// 进入微应用active() {// 保存window对象上所有属性的状态for (const prop in window) {this.windowSnapshot[prop] = window[prop];}// 恢复上一次在运行该微应用的时候修改过的window上的属性Object.keys(this.modifyPropsMap).forEach(prop => {window[prop] = this.modifyPropsMap[prop];});}// 离开微应用inactive() {for (const prop in window) {if (window[prop] !== this.windowSnapshot[prop]) {// 记录修改了window上的哪些属性this.modifyPropsMap[prop] = window[prop];// 将window上的属性状态还原至微应用运行之前的状态window[prop] = this.windowSnapshot[prop];}}}
}
javascript">window.city = 'Beijing';
let snapshotSanbox = new SanapshotSandbox();
console.log('====>window.city 01:', window.city);
snapshotSanbox.active();
window.city = 'Shanghai';
console.log('====>window.city 02:', window.city);
snapshotSanbox.inactive();
console.log('====>window.city 03:', window.city);snapshotSanbox.active();
console.log('====>window.city 04:', window.city);// ====>window.city 01: Beijing
// ====>window.city 02: Shanghai
// ====>window.city 03: Beijing
// ====>window.city 04: Shanghai

2 LegacySandbox沙箱

优点:

  • 不需要遍历window上所有的属性,性能良好;

缺点:

  • 同一时间只能激活一个微应用;
javascript">class LegacySandbox {modifiedPropsOriginalValueMapInSandbox = new Map(); // 修改属性addedPropsMapInSandbox = new Map(); // 新增的属性currentUpdatePropsValueMap = new Map(); // 所有变化的属性,包括修改的属性和新增的属性proxyWindow = {}; // 代理对象constructor() {const fakeWindow = Object.create(null);this.proxyWindow = new Proxy(fakeWindow, {set: (target, prop, value, receiver) => {const originalVal = window[prop];if (!window.hasOwnProperty(prop)) {this.addedPropsMapInSandbox.set(prop, value);} else if (!this.modifiedPropsOriginalValueMapInSandbox.has(prop)) {this.modifiedPropsOriginalValueMapInSandbox.set(prop, originalVal);}this.currentUpdatePropsValueMap.set(prop, value);window[prop] = value;},get: (target, prop, receiver) => {return window[prop];}})}setWindowProp(prop, value, isToDelete) {if (value === undefined && isToDelete) {delete window[prop];} else {window[prop] = value;}}active() {// 恢复上一次该微应用处于运行状态时,对window上做的所有修改this.currentUpdatePropsValueMap.forEach((value, prop) => {this.setWindowProp(prop, value);})}inactive() {// 还原window上原有的属性this.modifiedPropsOriginalValueMapInSandbox.forEach((value, prop) => {this.setWindowProp(prop, value);});// 删除在微应用运行期间,window上新增的属性this.addedPropsMapInSandbox.forEach((_, prop) => {this.setWindowProp(prop.undefined, true);})}
}
javascript">window.city = 'Beijing';
let legacySandbox = new LegacySandbox();
console.log('====>window.city 01:', window.city);
legacySandbox.active();
legacySandbox.proxyWindow.city = 'Shanghai';
console.log('====>window.city 02:', window.city);
legacySandbox.inactive();
console.log('====>window.city 03:', window.city);legacySandbox.active();
console.log('====>window.city 04:', window.city);// ====>window.city 01: Beijing
// ====>window.city 02: Shanghai
// ====>window.city 03: Beijing
// ====>window.city 04: Shanghai

3 ProxySandbox

优点:

  • 不需要遍历window上的所有属性,性能良好;
  • 同一时间可以激活多个微应用;
    缺点:
  • 只适用于支持 ES6语法 的浏览器(IE7-IE11不支持ES6);

使用工具如 Babel 将使用了 ES6+ 语法(包括 Proxy)的源代码转换为这些老旧浏览器能够理解的 ES5 或更低版本的 JavaScript 代码。Babel 可以通过配置相应的转译插件(如 @babel/plugin-transform-proxy)来尝试模拟 Proxy 行为,但这通常只能实现部分功能,并且性能和兼容性可能不如原生 Proxy

javascript">class ProxySandbox {proxyWindow = {};isRunning = false;constructor() {const fakeWindow = Object.create(null);this.proxyWindow = new Proxy(fakeWindow, {set: (target, prop, value, receiver) => {if(this.isRunning) {target[prop] = value;}},get: (target, prop, receiver) => {return prop in target ? target[prop]: window[prop];},});}active() {this.isRunning = true;}inactive() {this.isRunning = false;}
}
javascript">window.city = 'Beijing';
let proxtSandbox01 = new ProxySandbox();
let proxtSandbox02 = new ProxySandbox();
proxtSandbox01.active();
proxtSandbox02.active();
proxtSandbox01.proxyWindow.city = 'Shanghai';
proxtSandbox02.proxyWindow.city = 'Chendu';
console.log('====>proxtSandbox01.proxyWindow.city 01:', proxtSandbox01.proxyWindow.city);
console.log('====>proxtSandbox02.proxyWindow.city 01:', proxtSandbox02.proxyWindow.city);
console.log('====>window.city 01:', window.city);
proxtSandbox01.inactive();
proxtSandbox02.inactive();
console.log('====>proxtSandbox01.proxyWindow.city 02:', proxtSandbox01.proxyWindow.city);
console.log('====>proxtSandbox02.proxyWindow.city 02:', proxtSandbox02.proxyWindow.city);
console.log('====>window.city 02:', window.city);

http://www.ppmy.cn/devtools/5036.html

相关文章

软考126-上午题-【软件工程】-测试方法

一、测试方法 在软件测试过程中,应该为定义软件测试模板,即将特定的测试方法和测试用例设计放在一系列的测试步骤中。 软件测试方法分为:静态测试和动态测试。 1-1、静态测试。 静态测试是指被测试程序不在机器上运行,而是采用…

Linux下多版本cuda切换

参考博客 Linux多版本cuda切换_切换nvcc-CSDN博客

利用nvm安装npm失败的解决办法 Downloading npm version 6.14.18... Error while downloading

问题:用nvm安装nodejs版本,下载npm出错。 解决方法: 设置淘宝镜像 在安装路径下编辑setting.txt 添加以下两行镜像地址 node_mirror: https://registry.npmmirror.com/node/ npm_mirror: https://registry.npmmirror.com/npm/下载你想要的…

二分答案复习

y总二分查找算法模板 int bsearch_1(int l, int r) {while (l < r){int mid l r >> 1;//性质在右边&#xff0c;区间划分成[l, mid]和[mid 1, r]if (check(mid)) r mid;else l mid 1;}return l; }int bsearch_2(int l, int r) {while (l < r){int mid l r …

物联网实验

实验1 基于ZStack光敏传感器实验 1.实验目的 我们通过上位机发指令给协调器&#xff0c;协调器把串口接收到的指令通过Zigbee协议无线发送给带有光敏传感器的终端节点&#xff0c;获取到数据以后把数据返回给上位机&#xff0c;实现无线获取数据的目的。 2.实验设备 硬件&a…

Tcpdump -r 解析pcap文件

当我们使用命令抓包后&#xff0c;想在命令行直接读取筛选怎么办&#xff1f;-r参数就支持了这个 当你使用 tcpdump 的 -r 选项读取一个之前捕获的数据包文件&#xff0c;并想要筛选指定 IP 地址和端口的包时&#xff0c;你可以在命令中直接加入过滤表达式。这些过滤表达式可以…

CentOS常见的命令

CentOS&#xff08;Community ENTerprise Operating System&#xff09;是一个基于Red Hat Enterprise Linux源代码构建的开源企业级Linux发行版。在日常的系统管理和维护中&#xff0c;掌握一些常见的CentOS命令是非常必要的。本文将介绍一些CentOS系统中常用的命令&#xff0…

查看TensorFlow已训模型的结构和网络参数

文章目录 概要流程 概要 通过以下实例&#xff0c;你将学会如何查看神经网络结构并打印出训练参数。 流程 准备一个简易的二分类数据集&#xff0c;并编写一个单层的神经网络 train_data np.array([[1, 2, 3, 4, 5], [7, 7, 2, 4, 10], [1, 9, 3, 6, 5], [6, 7, 8, 9, 10]]…