本文介绍: 完成了一个简易沙箱,但是会遍历window的所有属性,非常消耗性能,方案不是很可取,与此同时,影响了window上的值,如果多个微应用就可能会产生冲,只能激活一个微应用。主应用和子应用,相同的全局变量,可能会发生冲突,子应用和子应用之间,相同的全局变量,也可能会发生冲突。不需要遍历window上的所有属性,性能良好,但是依然改变的是window上的值,但同一时间还是只能激活一个微应用。这种ProxySandBox不需要遍历window上的所有属性,性能良好,同一时间可以激活多个微应用互不干扰。
为什么要有js资源隔离机制?
主应用和子应用,相同的全局变量,可能会发生冲突,子应用和子应用之间,相同的全局变量,也可能会发生冲突。在这里我们主要指的就是window。
思路:打开沙箱时能够修改属性值;关闭沙箱时恢复未开启沙箱前的属性值,并且要记录修改了哪些属性。
qiankun.js隔离机制
SnapshotSandBox
class SnapShotBox {
windowSnap = {} //保存window上原本的属性值
modifyPropMap = {} //记录修改的属性
//微应用激活状态
active() {
//保存window对象上所有属性的状态
for (const prop in window) {
this.windowSnap[prop] = window[prop]
}
//恢复上一次在运行该微应用时所修改过的window上的属性
Object.keys(this.modifyPropMap).forEach(prop => {
window[prop] = this.modifyPropMap[prop];
})
}
//微应用未激活状态
inactive() {
for (const prop in window) {
//判断是否值发生了变化
if (window[prop] !== this.windowSnap[prop]) {
//记录修改了window上的哪些属性
this.modifyPropMap[prop] = window[prop]
//将window上的属性状态还原至微应用运行之前的状态
window[prop] = this.windowSnap[prop]
}
}
}
}
const snapShotBox = new SnapShotBox()
window.city = 'Beijing'
console.log(window.city); //Beijing
snapShotBox.active()
window.city = 'Shanghai'
console.log(window.city); //Shanghai
snapShotBox.inactive()
console.log(window.city); //Beijing
完成了一个简易沙箱,但是会遍历window的所有属性,非常消耗性能,方案不是很可取,与此同时,影响了window上的值,如果多个微应用就可能会产生冲,只能激活一个微应用。
LegacySandBox
class LegacySandBox {
currentUpdatePropsValueMap = new Map() //微应用中修改的属性
modifiedPropsOriginValueMapInSanBox=new Map()//window中被修改的属性
addedPropsMapInSandBox=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)){ //如果window上没有这个属性,那么就是新增的属性
this.addedPropsMapInSandBox.set(prop,value)
//如果修改对象中没有这个属性,就保存一下
}else if(!this.modifiedPropsOriginValueMapInSanBox.has(prop)){
this.modifiedPropsOriginValueMapInSanBox.set(prop,originalVal)
}
this.currentUpdatePropsValueMap.set(prop,value)
window[prop] = value
},
get:(target,prop,receiver)=>{
return window[prop]
},
})
}
//设置window属性
setWindowProp(prop, value, isToDelete) {
if (value == "undfined" && isToDelete) {
delete window[prop]
} else {
window[prop] = value
}
}
//微应用激活状态
active() {
//恢复上一次在运行该微应用时所修改过的window上的属性
this.currentUpdatePropsValueMap.forEach((value, prop) => {
this.setWindowProp(prop, vaue);
})
}
//微应用未激活状态
inactive() {
//还原window上原有的属性
this.modifiedPropsOriginValueMapInSanBox.forEach((value,prop)=>{
this.setWindowProp(prop,value)
})
//删除微应用运行期间,window上新增的属性
this.addedPropsMapInSandBox.forEach((_,prop)=>{
this.setWindowProp(prop,undefined,true)
})
}
}
let legacySandbox = new LegacySandBox()
window.city = 'Beijing'
console.log(window.city); //Beijing
snapShotBox.active()
window.city = 'Shanghai'
console.log(window.city); //Shanghai
snapShotBox.inactive()
console.log(window.city); //Beijing
不需要遍历window上的所有属性,性能良好,但是依然改变的是window上的值,但同一时间还是只能激活一个微应用。
ProxySandBox
class ProxySandBox {
proxyWindow;
isRunning = false
//微应用激活状态
active() {
this.isRunning = true
}
//微应用未激活状态
inactive() {
this.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]
}
})
}
}
window.city = 'Beijing'
let proxySandBox01 = new ProxySandBox()
let proxySandBox02 = new ProxySandBox()
proxySandBox01.active()
proxySandBox02.active()
proxySandBox01.proxyWindow.city = "Shanghai"
proxySandBox02.proxyWindow.city = "Tianjing"
console.log(window.city, proxySandBox01.proxyWindow.city, proxySandBox02.proxyWindow.city);
//Beijing Shanghai Tianjing
proxySandBox01.inactive()
proxySandBox02.inactive()
console.log(window.city, proxySandBox01.proxyWindow.city, proxySandBox02.proxyWindow.city);
//Beijing Shanghai Tianjing
这种ProxySandBox不需要遍历window上的所有属性,性能良好,同一时间可以激活多个微应用互不干扰。
SnapshotSandBox兼容性很好,ProxySandBox适用于es6的语法中,就简单介绍到这里。
原文地址:https://blog.csdn.net/m0_59962790/article/details/134755546
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.7code.cn/show_32930.html
如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。