UNPKG

mustard-app

Version:

个人前端微应用建设中。。。

139 lines (128 loc) 5.5 kB
import { ProxyEventListener }from './proxyEventListener'; import { proxyDocument }from './proxyDocument'; import { proxyHistory }from './proxyHistory'; import { proxyLocation }from './proxyLocation'; import { proxyLocalStorage, proxySessionStorage }from './proxyStorage'; import { MustardName, MustardURL } from '../typings'; import { EventCenterMicroApp } from '../communication'; export class SandBox { active = false; // 沙箱是否在运行 microWindow = {}; // 代理的对象 injectedKeys = new Set<string | symbol>(); // 新添加的属性,在卸载时清空 name:MustardName; // 沙箱标识同app标识一致 proxyEventListener:ProxyEventListener; // 全局事件代理 proxyWindow; // window 代理 proxyDocument; // document 代理 proxyHistory; // history 代理 proxyLocation; // location 代理 proxyLocalStorage; // localStorage 代理 proxySessionStorage; // sessionStorage 代理 microApp: EventCenterMicroApp; // 事件通讯 // todo // url: MustardURL constructor (name:MustardName, url: MustardURL) { this.name = name; this.proxyLocation = proxyLocation(this.name, url); this.proxyHistory = proxyHistory(this.name); this.proxyLocalStorage = proxyLocalStorage(this.name); this.proxySessionStorage = proxySessionStorage(this.name); this.proxyDocument = proxyDocument(this.name); this.proxyEventListener = new ProxyEventListener(); this.microApp = new EventCenterMicroApp(this.name); this.proxyWindow = new Proxy(this.microWindow, { // 取值 get: (target, key) => { // 优先从代理对象上取值 if (Reflect.has(target, key)) { return Reflect.get(target, key); } if(key === 'document') { return this.proxyDocument; } if(key === 'addEventListener') { return this.proxyEventListener.addEventListener.bind(this.proxyEventListener); } if(key === 'history') { return this.proxyHistory; } if(key === 'location') { return this.proxyLocation; } if(key === 'localStorage') { return this.proxyLocalStorage; } if(key === 'sessionStorage') { return this.proxySessionStorage; } if(key === 'microApp') { return this.microApp; } // 否则兜底到window对象上取值 const rawValue = Reflect.get(window, key); // 如果兜底的值为函数,则需要绑定window对象,如:console、alert等 if (typeof rawValue === 'function') { const valueStr = rawValue.toString(); // 排除构造函数 if (!/^function\s+[A-Z]/.test(valueStr) && !/^class\s+/.test(valueStr)) { return rawValue.bind(window); } } // 其它情况直接返回 return rawValue; }, // 设置变量 set: (target, key, value) => { // 沙箱只有在运行时可以设置变量 if (this.active) { Reflect.set(target, key, value); // 记录添加的变量,用于后续清空操作 this.injectedKeys.add(key); } return true; }, deleteProperty: (target, key) => { // 当前key存在于代理对象上时才满足删除条件 if (Object.prototype.hasOwnProperty.call(target, key)) { return Reflect.deleteProperty(target, key); } return true; }, has (target, key) { return key in target || key in window; } }); } start () { if(!this.active) { this.active = true; } } stop () { if(this.active) { this.microApp.clearDateListener(); this.active = false; Array.from(this.injectedKeys.keys()).forEach(key => Reflect.deleteProperty(this.microWindow, key)); this.injectedKeys.clear(); this.proxyEventListener.clear(); } } // 修改js作用域 bindScope (code) { return ` ;(function(window, self){ const microApp = window.microApp; const history = window.history; const location = window.location; const document = window.document; const localStorage = window.localStorage; const sessionStorage = window.sessionStorage; const addEventListener = window.addEventListener; ${code}\n; }).call( mustardAppInfos.getAppProxyWindow('${this.name}'), mustardAppInfos.getAppProxyWindow('${this.name}'), mustardAppInfos.getAppProxyWindow('${this.name}'), ) `; } }