代理沙箱 支持多个微应用同时运行
代码来自一篇qiankun文章
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;
}
}
// 验证:
let proxySandBox1 = new ProxySandBox();
let proxySandBox2 = new ProxySandBox();
proxySandBox1.active();
proxySandBox2.active();
proxySandBox1.proxyWindow.city = 'jinan';
proxySandBox2.proxyWindow.city = 'nanjing';
console.log('active:proxySandBox1:window.city:', proxySandBox1.proxyWindow.city); // jinan
console.log('active:proxySandBox2:window.city:', proxySandBox2.proxyWindow.city); // nanjing
console.log('window:window.city:', window.city); // undefined
proxySandBox1.inactive();
proxySandBox2.inactive();
console.log('inactive:proxySandBox1:window.city:', proxySandBox1.proxyWindow.city); // jinan
console.log('inactive:proxySandBox2:window.city:', proxySandBox2.proxyWindow.city); // nanjing
console.log('window:window.city:', window.city); // undefined
代码梳理
1.实例化两个沙箱proxySandBox1 proxySandBox2
2.分别激活,将isRunning设置为true
3.分别设置不同沙箱里的proxyWindow对象的属性city值,因为修改了代理对象proxyWindow,所以会触发其set回调,将新增属性及值设置到target上
4.此时到console打印位置,proxySandBox1.proxyWindow.city会触发proxy的get回调,三元判断如果该属性在target就返回,否则就去返回window上的该属性,始终不会去污染window
至此,逻辑已经理清,通过proxy实现了在各自环境维护状态,与window进行了解耦,所以可以支持多个应用同时运行。
最后总结,这是关于qiankun实现js隔离的沙箱核心逻辑的简要梳理,各位有更好的理解可以在评论区交流。