阿里的飞冰项目里的微前端中出现沙箱概念。这是为了隔离子应用对全局变量window的影响。我们先思考下有哪些影响:
- 子应用共用了同一个全局变量,并可能进行修改。
- 定时器,app离开前没有清理的话,可能会导致报错,内存溢出。
- 事件的监听,同样app离开前没有清理的话,可能会导致报错,内存溢出。
- 子应用新增了一个全局变量,app离开前没有清理的,内存溢出。
当然,如果子应用使用了主框架提供的enter和leave的生命周期,同时注意代码的健壮性,上面的4个影响都可以各子应用处理,沙箱就没有存在的必要了。毕竟又包了一层,又使用了浏览器不好优化的with,还是影响性能的。
再了解过with这个语法后,再看飞冰项目中沙箱的实现就觉得十分浅显了,就是proxy和with。proxy代理了对沙箱的访问,with修改当前作用域为沙箱,proxy实例的get把所有指向window的改为指向本身,这样子应用就不能直接访问到window了。接下来就只处理可能产生的影响。
- 保存所有新增属性,离开前删除。(保存通过proxy.get)
- 保存待修改属性的原始值,离开前恢复。(保存通过proxy.get)
- 保存所有事件监听的function,离开前移除监听。(保存通过包装addEventListener和removeEventListener)
4 保存所有定时器ID,离开前移除。(保存通过包装setTimeout和setInterval)
其实这不算严格意义上的沙箱(不过前端就不好实现),毕竟还是可能会对主应用造成影响,主要是子应用间的隔离,特别是没有遵循飞冰框架推荐实现的的子应用。