嵌套场景
Garfish 目前的源码设计并没有针对嵌套场景进行非常好的兼容,但是用户在某些场景又不得不使用嵌套的模式开发微前端应用,通过 Garfish 的设计一定程度上也能满足嵌套场景的诉求,但是在实际使用的过程中存在一些限制。
Garfish 为什么不容易支持嵌套场景
在正式介绍如何在嵌套场景下使用前,先简单介绍一下为什么 Garfish 现在并不推荐用户使用嵌套模式的原因:
Garfish导出的是实例不是构造函数,多个项目通过npm包的方式引用始终都是同一个实例(Garfish 最终并没有考虑多实例的情况),因此嵌套场景下使用的都是同一个Garfish实例,同一个实例会带来很明显的弊端,全局配置会影响其他应用的使用Garfish路由驱动会劫持history等方法,沙箱会劫持dom的原型方法,这些劫持方法再应用销毁后进行恢复成本较高
嵌套场景如何使用
名称统一约束
由于在支持嵌套场景前,在 Garfish 中仅有两种项目类型:一种是主应用,另外一种是子应用,但是在支持嵌套场景后,他们的关系会有更多层次,因此约束一下他们之间的名称:
- 「子应用」:本身就是一个单纯的应用,本身不包含其他应用
- 「主应用」:包含其他的子应用,本身不作为子应用使用
- 「微主应用」:包含其他子应用,并且本身也作为其他主应用的子应用
使用约束
在 「Garfish 为什么不容易支持嵌套场景」一节中提到 Garfish 目前的整体设计并不太适合嵌套场景的使用,因此希望通过一些约束来减少上述的使用问题,并且将约束后可能产生的影响也同步给用户,让用户根据实际情况进行判断。
由于 Garfish 并未直接导出构造函数,而是通过直接导出 Garfish 实例,因此在实际使用中要尽可能的避免实例上全局配置带来的影响:
- 「主应用」、「微主应用」都不要使用
Garfish.run、Garfish.setOptions, 这两个API都会直接更改Garfish实例上的全局配置,可以通过Garfish.loadApp的方式加载子应用,这样可以保证不会对Garfish实例的全局配置产生影响 - 如果「主应用」使用了
Garfish.run的注意事项- 将配置放到
AppInfo维度,这样不会对全局所有的App实例生效,只会对实际使用的 App 生效,这样会尽可能减少全局配置 - 在
Garfish.run中配置的生命周期函数不仅会触发主应用配置的加载、渲染销毁的hook,在嵌套场景中「微主应用」的加载渲染子应用也会触发,因为嵌套场景使用的是同一个Garfish实例 - 作为「微主应用」要清楚主应用上的全局配置,例如比较关键的沙箱配置,这些配置都会直接影响「微主应用」加载子应用的行为
- 将配置放到
- 「微主应用」如何判断是由「主应用」加载的,需要主应用增加环境变量例如:
window.__GARFISH_PARENT__ = true等标识,这个时候「微主应用」可以根据标识决定是否独立渲染 - 「微主应用」中需要保证应用的
name不会与「主应用」列表的name不会发生冲突,因此为微主应用的子应用name增加特殊前缀避免与主应用发生冲突 - 在使用
Garfish.router、Garfish.channel等实例上的方法时,可能会受到「主应用」、「微主应用」的影响,例如:Garfish.router.push的basename如果在「主应用」或者「微主应用」中设置了全局的basenameGarfish.channel的实例在「主应用」或者「微主应用」都是同一个,如果使用了相同的事件名或者回调函数会互相应用- 在使用基础类型时都需要注意这些问题
Garfish包的升级,会同时影响、主应用和微主应用
约束总结
- 不要使用
Garfish.run、Garfish.setOptionsAPI、避免修改Garfish全局配置 - 主应用增加环境标识,通过环境判断让微主应用能够独立运行
- 将配置信息以子应用维度存放,放置
AppInfo中 Garfish.loadApp的方式加载、渲染微前端子应用- 使用
Garfish实例的方法时,需要注意默认配置是否收到了全局配置或其他应用的影响 Garfish包的升级,会同时影响、主应用和微主应用 :::