qiankun(微前端)快问快答

1,519 阅读6分钟

去友商做了一次小范围的微前端相关分享,收集到了几个比较经典的问题,值得记录一下:

Q: qiankun 在性能优化、提升子应用打开速度方面做了哪些工作? A: 最基本的有 prefetch 这种配置,开了这个配置可以提前将一些还不需要渲染的微应用的静态资源做一下预加载。 Q:实践中会有微应用特别多,预加载请求就会很多的情况。 A: prefetch 可以配置成数组的形式,指定加载哪些微应用。如果有平台级别的数据统计方案,prefetch 对应的数组可以根据应用打开率动态决策。

Q: 主子应用样式隔离、切换应用时 dom 副作用的清除有哪些比较好的方案 A: 主子应用的样式隔离还是推荐构建时统一配置 prefix 的方案,比如 antd 就有这类配置,qiankun 官网也是这么推荐的。不过目前 qiankun 也有一个运行时隔离的方案,将子应用的 class 在运行时加一个统一的前缀,保证不会出现冲突。不过会有一定的性能损耗,而且那种全局样式的继承导致的冲突问题也很难避免。 DOM 的副作用 qiankun 默认没有做,只针对动态的脚本跟样式做了劫持,不过要做也是可以做的,比如在 beforeMount、afterMount 钩子里拿到沙箱实例,然后做一些自定义的劫持行为,但总的来说不太推荐,3.0 会提供更方便的 api。

Q: 如何实现主应用对子应用运行时的管控,比方说 CDN 故障时进行统一的切流? A: 没有做,蚂蚁内部静态资源都是发 render,一个内部的基建产品,它自己做了 CDN 故障降级这类事情,可以无限信赖(笑)。

Q: 如何实现对 localStorage/cookie 等进行隔离,localStorage[key] 、response set-Cookie 等如何处理 A: 沙箱里默认行为也是没有的,因为我们当时实践的场景是,隔离 localStorage/cookie 带来的麻烦可能比收益会更多。因为大部分时候恰好是希望共享 cookie 或者 localStorage 的,比如登录这种场景。如果确实需要,也可以自己在钩子里拿到沙箱实例,植入自定义行为。

Q: 是否支持 vite 来构建应用? A: 不支持。因为 esm 的机制导致我们现在没办法把 js 拿来做手动 evaluate,因为我们要支持沙箱。 追问:我看社区好像有 qiankun + vite 的方案? A: 那它肯定不支持沙箱(笑)。

Q: 复用依赖除了 module federation 外支持 import maps 吗 A: 不支持,原因跟上面一样,import maps 是 esm 的加载方式,这种现在都没办法支持沙箱。而且现在要用 import maps 的话,你都得基于一个统一 loader 来加载应用,比如 systemjs,这样的话我就跟倾向于 module federation 这种现在更普适的方案了。

Q: 除「页面级」微前端外,有什么非 NPM / UMD 形式的「微组件」解决方案吗 A: 我们内部的微应用全部都是 HTML Entry 的,就是产物都是 HTML,不论是页面还是组件,这也是 qiankun 推荐的方式,因为非 HTML Entry 的模式,会带来很多研发流程上的问题。

Q: 有考虑使用 realm api 来实现沙盒 A: qiankun 3.0 的 Roadmap 有提到这个,realm 现在已经改名称 ShadowRealm 了,3.0 我们会 follow ShadowRealm 的 api 来设计沙箱,但基本不可能直接用它。因为如果你看过 ShadowRealm 的提案内容的话,会发现它的隔离机制比 iframe 还要严格,iframe 还能通过 window.top 这种方式访问宿主,通过共享 contentWindow 传递变量,但这些在 ShadowRealm 里都被禁止了。我觉得 ShadowRealm 设计出来主要是用来加载三方不可信赖脚本的,而微前端场景更多解决的是二方研发场景,没必要上这么严格的限制,这么严格的限制反而会带来一些不便。

Q: 阿里云还有个 alfajs 的方案,使用 iframe 进行隔离,传入 location, history, setTimeout , qiankun proxy 的方案和他相比优点在哪? A: 刚好最近腾讯也公开了一个基于 iframe 的微前端方案,但是还没开源。iframe 方案会在产品体验上碰到比较多的问题,举个例子,我通过 iframe 渲染了一个页面,单是要解决外层 iframe 容器要自适应内容高度的问题可能就已经很麻烦了,比如你要在 iframe 里面监听 DOMContentLoaded 事件,然后把渲染后的内容高度通过 postMessage 传回给外部,类似的问题还有很多。

Q: 对目前出现的一些其他微前端框架(Micro-app, Garfish, ICESTARK 等...)有了解吗?如何评价? A: 有了解,但是利益相关,我不能评价,你们懂的(笑)。

Q: qiankun 短、中、远期在产品上有什么规划? A: 我们最近在筹备 3.0,Roadmap 都公开在 github 上。3.0 里一个主要的功能是会把沙箱开放出去,可以让开发者自己根据场景制定沙箱规则。比如上面提到的,有的场景你希望更严格的沙箱,比如劫持 localStorage 的读写,但是默认沙箱里没有做,那你可以直接通过 api 把逻辑加进去,或者有的场景你觉得默认沙箱又太严格,希望共享一些东西,那就可以通过一些配置,把默认的行为关掉一些。

Q: 你所了解的微前端子模块一般都是如何划分的?有什么建议? A: 我的 PPT 里有一页其实提到了,微前端拆分其实需要有明确的服务边界划分。如果你的微应用之间存在了过多的交互或者耦合,那你可能就要考虑是不是拆分的粒度过细了。 有一个简单的判断方式,就是看你的微应用在独立打开的情况下,是否能完成一个独立 功能/服务 的提交,如果不是的,那可能就要看看了。

Q: 开发实现上子模块希望隔离,但用户真实使用是有聚合(页面甚至平台级组合)诉求的,有没有好的经验分享解决这样的问题? 问问题的同学好像说 PPT 分享里好像已经提过了,就没有单独回答了。