美文网首页
118.深度学习qiankun-LegacySandBox

118.深度学习qiankun-LegacySandBox

作者: wo不是黄蓉 | 来源:发表于2022-11-03 10:33 被阅读0次
深度学习qiankun-LegacySandBox

原理:和快照沙箱原理相同,是对快照沙箱的完善。不同是LegacySandBox使用es6的proxy,使用代理可以不用直接修改window上的属性,卸载时可以直接卸载不用遍历所有window上的属性进行对比再卸载

缺点:多个子应用还是会写在window上会相互影响,只支持同时运行一个子应用,多应用解决方案,使用ProxySandBox

简易版实现:

//获取属性是否可配置
function isConfigurable(target, prop) {
  const descriptors = Object.getOwnPropertyDescriptor(target, prop);
  return descriptors ? descriptors.configurable : true;
}

//设置属性
function setWindowProp(prop, value, toDelete) {
  if (value === undefined && toDelete) {
    delete window[prop];
  } else if (isConfigurable(window, prop) && typeof prop !== "symbol") {
    Object.defineProperty(window, prop, {
      writable: true,
      configurable: true,
    });
    window[prop] = value;
  }
}

//代理实现
class LegacySandbox {
  addedPropsMapInSandbox = new Map(); //存放新增的全局变量,用于卸载时重置属性
  modifiedPropsOriginalValueMapInSandbox = new Map(); //存放修改的全局变量
  currentUpdatedPropsValueMap = new Map(); //存放运行期的所有变量
  sandboxRunning = true;
  proxy = null;

  active() {
    //新增时注册变量
    this.currentUpdatedPropsValueMap.forEach((value, prop) =>
      setWindowProp(prop, value)
    );
    this.sandboxRunning = true;
  }

  inactive() {
    this.modifiedPropsOriginalValueMapInSandbox.forEach((v, p) =>
      setWindowProp(p, v)
    );
    this.addedPropsMapInSandbox.forEach((_, p) =>
      setWindowProp(p, undefined, true)
    );
    this.sandboxRunning = false;
  }

  constructor() {
    const fakeWindow = Object.create(null);
    //把window上的属性都代理到fakeWindow上,使用proxy不用每次都遍历所有window上的属性
    this.proxy = new Proxy(fakeWindow, {
      set: (target, propKey, value, receiver) => {
        //获取window上的属性
        const originalValue = window[propKey];
        //window上不存在这个新增的属性,记录到addedPropsMapInSandbox
        if (!window.hasOwnProperty(propKey)) {
          this.addedPropsMapInSandbox.set(propKey, value);
        } else if (!this.modifiedPropsOriginalValueMapInSandbox.has(propKey)) {
          //window上存在这个属性了,说明是更新,记录到modifiedPropsOriginalValueMapInSandbox
          this.modifiedPropsOriginalValueMapInSandbox.set(
            propKey,
            originalValue
          );
        }
        //当前活动的属性,记录到currentUpdatedPropsValueMap
        this.currentUpdatedPropsValueMap.set(propKey, value);
        window[propKey] = value;
      },
      get: (target, propKey, receiver) => {
        return target[propKey];
      },
    });
  }
}

let legacySandBox = new LegacySandbox();
legacySandBox.active();
legacySandBox.proxy.app = "vue2";
console.log("window.app-01:", window.app);
legacySandBox.inactive();
console.log("window.app-02:", window.app);
legacySandBox.active();
console.log("window.app-03:", window.app);
legacySandBox.inactive();

源码实现

相关文章

网友评论

      本文标题:118.深度学习qiankun-LegacySandBox

      本文链接:https://www.haomeiwen.com/subject/wuastdtx.html