Skip to content

项目背景

目前 4.0 项目中采用 Platform + App 的架构模式,Platform 作为应用的基座,通过 single-spa 加联邦模块的形式控制 App 的加载与卸载。但是这种架构模式下存在一些问题:

css 样式相互影响问题

问题描述

当 Platform 加载和卸载 App 时,由于样式文件都是“全局”性质的,导致 Platform 和 App 间、不同 App 间的样式可能存在覆盖问题,并且这种影响是不可控的。

当前解决方案

当前采用 App 前缀 + 组件前缀的方式进行解决。Platform 和 每个 App 都有各自的类名前缀,同时也包含各自的组件库前缀。样式覆盖时,使用各自的前缀进行覆盖,能够有效地减少 App 间样式相影响的问题。

此外,在 App 卸载时,当前方案会将相应的 App 样式文件卸载,以保证 App 间的样式互不影响。

当前方案的不足

  • 由于 Platform 与 App 存在嵌套关系,这种方式依然无法避免 Platform 的样式影响 App 样式的可能性。
  • 需要组件库配合提供前缀的功能,目前 design 组件库提供了前缀的功能,但是 ui / shared 组件库未提供,对 ui / shared 进行样式覆盖依旧存在问题。
  • 不能保证 App 资源加载和卸载的时序是完全正确的。
  • 当前方案基于规范的约束,如果开发人员未遵循规范,依然会产生样式影响的问题。

svg 命名重复问题

问题描述

由于 Platform / App 都采用 svg-sprite-loader 处理 svg,Platform / App 最终生成一个共同的 svg,如果 Platform / App 重名,就会产生 svg 被覆盖的问题。

当前解决方案

当 App 卸载时,会人为的卸载对应的 svg 节点,类似于 css 的解决方案。 虽然卸载了 svg,但是又存在个别 App 卸载失败的问题,因此又在 Platform / App 打包的时候为 svg 加上统一前缀。

当前方案的不足

  • 该方案能解决问题,并未做到 Platform / App 资源间完全的隔离。

js 文件名称冲突问题

问题描述

在联邦模块中,APP 将 shared 依赖打包后 chunkid(当前使用默认值:短数字 chunkid) 可能会出现相同的情况,导致 app2 根据 chunkid 加载到 app1 的 js。

当前解决方案

通过 webpack 为打包后的 chunk id 加上项目前缀。

当前方案的不足

  • 同 svg 方案,资源未完全隔离

js 异步操作问题

问题描述

如果 App 内部存在异步请求,当 App 卸载后,css 文件已经被卸载。此时异步请求拿到结果,打开弹出提示,会发现 css 样式已经不存在,导致弹窗内容显示异常。

当前解决方案

统一对请求标记来源,当检测到为跨 App 时,不会响应请求结果。

当前方案的不足

理想情况下,App 卸载后没有相关的 DOM 结构,js 的执行也不会对非 App 的 DOM 进行操作。这里只约束了请求这一种场景,但其他的异步操作也有可能会存在该问题。

总结

以上只是比较重要的几个问题,除此之外还存在一些其他的问题。

在当前架构下,html/css/js 资源均未做到隔离,导致资源间存在相互影响的问题。并且需要通过大量的约束和规范来保证资源间不会产生影响,开发成本较高,心智负担较大,并且结果不可控。

因此,需要一种新的架构模式来解决这些问题,并且能够保证资源间不会产生影响。