嵌套场景
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
如果在「主应用」或者「微主应用」中设置了全局的basename
Garfish.channel
的实例在「主应用」或者「微主应用」都是同一个,如果使用了相同的事件名或者回调函数会互相应用- 在使用基础类型时都需要注意这些问题
Garfish
包的升级,会同时影响、主应用和微主应用
约束总结
- 不要使用
Garfish.run
、Garfish.setOptions
API、避免修改Garfish
全局配置 - 主应用增加环境标识,通过环境判断让微主应用能够独立运行
- 将配置信息以子应用维度存放,放置
AppInfo
中 Garfish.loadApp
的方式加载、渲染微前端子应用- 使用
Garfish
实例的方法时,需要注意默认配置是否收到了全局配置或其他应用的影响 Garfish
包的升级,会同时影响、主应用和微主应用 :::