微前端沙箱有2种实现方式:快照与代理。
代理实现沙箱
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}}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);
快照实现沙箱
class SnapshotSandbox {constructor() {this.modifyPropsMap = {}; // 修改了那些属性}active() {this.windowSnapshot = {}; // window对象的快照for (const prop in window) {if (window.hasOwnProperty(prop)) {// 将window上的属性进行拍照this.windowSnapshot[prop] = window[prop];}}Object.keys(this.modifyPropsMap).forEach(p => {window[p] = this.modifyPropsMap[p];});}inactive() {for (const prop in window) { // diff 差异if (window.hasOwnProperty(prop)) {// 将上次拍照的结果和本次window属性做对比if (window[prop] !== this.windowSnapshot[prop]) {// 保存修改后的结果this.modifyPropsMap[prop] = window[prop];// 还原windowwindow[prop] = this.windowSnapshot[prop];}}}}}let sandbox = new SnapshotSandbox();window.a = 1;sandbox.active();window.b = 2;window.c = 3console.log(a,b,c)sandbox.inactive();console.log(a,b,c)
