跳到主要内容

嵌套场景

Garfish 目前的源码设计并没有针对嵌套场景进行非常好的兼容,但是用户在某些场景又不得不使用嵌套的模式开发微前端应用,通过 Garfish 的设计一定程度上也能满足嵌套场景的诉求,但是在实际使用的过程中存在一些限制。

Garfish 为什么不容易支持嵌套场景

在正式介绍如何在嵌套场景下使用前,先简单介绍一下为什么 Garfish 现在并不推荐用户使用嵌套模式的原因:

  • Garfish 导出的是实例不是构造函数,多个项目通过 npm 包的方式引用始终都是同一个实例(Garfish 最终并没有考虑多实例的情况),因此嵌套场景下使用的都是同一个 Garfish 实例,同一个实例会带来很明显的弊端,全局配置会影响其他应用的使用
  • Garfish 路由驱动会劫持 history 等方法,沙箱会劫持 dom 的原型方法,这些劫持方法再应用销毁后进行恢复成本较高

嵌套场景如何使用

名称统一约束

由于在支持嵌套场景前,在 Garfish 中仅有两种项目类型:一种是主应用,另外一种是子应用,但是在支持嵌套场景后,他们的关系会有更多层次,因此约束一下他们之间的名称:

  • 「子应用」:本身就是一个单纯的应用,本身不包含其他应用
  • 「主应用」:包含其他的子应用,本身不作为子应用使用
  • 「微主应用」:包含其他子应用,并且本身也作为其他主应用的子应用

使用约束

在 「Garfish 为什么不容易支持嵌套场景」一节中提到 Garfish 目前的整体设计并不太适合嵌套场景的使用,因此希望通过一些约束来减少上述的使用问题,并且将约束后可能产生的影响也同步给用户,让用户根据实际情况进行判断。

由于 Garfish 并未直接导出构造函数,而是通过直接导出 Garfish 实例,因此在实际使用中要尽可能的避免实例上全局配置带来的影响:

  • 「主应用」、「微主应用」都不要使用 Garfish.runGarfish.setOptions, 这两个 API 都会直接更改 Garfish 实例上的全局配置,可以通过 Garfish.loadApp 的方式加载子应用,这样可以保证不会对 Garfish 实例的全局配置产生影响
  • 如果「主应用」使用了 Garfish.run 的注意事项
    • 将配置放到 AppInfo 维度,这样不会对全局所有的 App 实例生效,只会对实际使用的 App 生效,这样会尽可能减少全局配置
    • Garfish.run 中配置的生命周期函数不仅会触发主应用配置的加载、渲染销毁的 hook,在嵌套场景中「微主应用」的加载渲染子应用也会触发,因为嵌套场景使用的是同一个 Garfish 实例
    • 作为「微主应用」要清楚主应用上的全局配置,例如比较关键的沙箱配置,这些配置都会直接影响「微主应用」加载子应用的行为
  • 「微主应用」如何判断是由「主应用」加载的,需要主应用增加环境变量例如:window.__GARFISH_PARENT__ = true 等标识,这个时候「微主应用」可以根据标识决定是否独立渲染
  • 「微主应用」中需要保证应用的 name 不会与「主应用」列表的 name 不会发生冲突,因此为微主应用的子应用 name 增加特殊前缀避免与主应用发生冲突
  • 在使用 Garfish.routerGarfish.channel 等实例上的方法时,可能会受到「主应用」、「微主应用」的影响,例如:
    • Garfish.router.pushbasename 如果在「主应用」或者「微主应用」中设置了全局的 basename
    • Garfish.channel 的实例在「主应用」或者「微主应用」都是同一个,如果使用了相同的事件名或者回调函数会互相应用
    • 在使用基础类型时都需要注意这些问题
  • Garfish 包的升级,会同时影响、主应用和微主应用
约束总结
  • 不要使用 Garfish.runGarfish.setOptions API、避免修改 Garfish 全局配置
  • 主应用增加环境标识,通过环境判断让微主应用能够独立运行
  • 将配置信息以子应用维度存放,放置 AppInfo
  • Garfish.loadApp 的方式加载、渲染微前端子应用
  • 使用 Garfish 实例的方法时,需要注意默认配置是否收到了全局配置或其他应用的影响
  • Garfish 包的升级,会同时影响、主应用和微主应用 :::