qiankun
的 css
沙箱的原理是重写 HTMLHeadElement.prototype.appendChild
事件,记录子项目运行时新增的 style/link
标签,卸载子项目时移除这些标签。
single-spa
方案中我用了换肤的思路来解决 css
污染:首先 css-scoped
解决大部分的污染,对于一些全局样式,在子项目给 body/html
加一个唯一的 id/class
(正常开发部署用),然后这个全局的样式前面加上这个 id/class
,而 single-spa
模式则在 mount
周期给 body/html
加上这个唯一的 id/class
,在 unmount
周期去掉,这样就可以保证这个全局 css
只对这个项目生效了。
这两个方案的致命点都在于无法解决多个子项目同时运行时的 css
污染,以及子项目对主项目的 css
污染。
虽然说两个项目同时运行常见并不常见,但是如果想实现 keep-alive
,就需要使用 display: none
将子项目隐藏起来,子项目不需要卸载,这时候就会存在两个子项目同时运行,只不过其中一个对用户不可见。
css
沙箱还有个思路就是将子项目的样式局限到子项目的容器范围内生效,这样只需要给不同的子项目不同的容器就可以了。但是这样也会有新的问题,子项目中 append
到 body
的弹窗,样式就无法生效。所以说样式污染还需要制定规范才行,约定 class
命名前缀