跳到主要内容

认识

2024年09月04日
柏拉文
越努力,越幸运

一、认识


在微前端的场景,由于多个独立的应用被组织到了一起,在没有类似 iframe 的原生隔离下,势必会出现冲突,如全局变量冲突、样式冲突,这些冲突可能会导致应用样式异常,甚至功能不可用。通常,子应用在运行期间会有一些污染性的副作用产生,比如全局变量、全局事件、定时器、网络请求、localStorage、全局 Style 样式、全局 DOM 元素等。

所以想让微前端达到生产可用的程度,保证应用能够稳定的运行且互不影响,需要提供安全的运行环境,能够有效地隔离、收集、清除应用在运行期间所产生的副作用,让每个子应用之间达到一定程度隔离的沙箱机制是必不可少的,这就是沙箱的设计目标。

JavaScript 沙箱隔离 是主应用与子应用之间的隔离和子应用与子应用之间的隔离。JavaScript 沙箱隔离的方式 主要有两种: 一种是快照拷贝的方式,一个是基于 proxy 的方式。

二、快照沙箱


快照沙箱 SnapshotSandbox 在创建微应用的时候会实例化一个沙盒对象,它有两个方法,active 是在激活微应用的时候执行,而 inactive 是在离开微应用的时候执行。

整体的思路是在激活微应用时将当前的 window 对象 拷贝存起来,然后从 modifyPropsMap 中恢复这个微应用上次修改的属性到 window 中。在离开微应用时会与原有的 window 对象 做对比,将有修改的属性保存起来,以便再次进入这个微应用时进行数据恢复,然后把有修改的属性值恢复到以前的状态。

三、代理沙箱


代理沙箱 ProxySandbox 微应用中的 script 内容都会加 with(global) 来执行,这里 global 是全局对象,如果是 proxy 的隔离方式那么他就是下面新创建的 proxy 对象。

我们知道 with 可以改变里面代码的作用域,也就是我们的微应用全局对象会变成下面的这个 proxy。当设置属性的时候会设置到 proxy 对象 里,在读取属性时先从 proxy 里找,没找到再从原始的 window 中找。也就是你在微应用里修改全局对象的属性时不会在 window 中修改,而是在 proxy 对象 中修改。因为不会破坏 window 对象,这样就会隔离各个应用之间的数据影响。