qiankun的js隔离机制-沙箱(三)

71 阅读1分钟

代理沙箱 支持多个微应用同时运行

代码来自一篇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隔离的沙箱核心逻辑的简要梳理,各位有更好的理解可以在评论区交流。