Skip to content

single-spa 与 qiankun

single-spa 就做了两件事,加载微应用(加载方法还是用户自己提供的)、维护微应用状态(初始化、挂载、卸载)。了解多了会发现 single-spa 虽好,但是却存在一些比较严重的问题.

  1. 对微应用的侵入性太强 single-spa 采用 JS Entry 的方式接入微应用。微应用改造一般分为三步:
    • 微应用路由改造,添加一个特定的前缀
    • 微应用入口改造,挂载点变更和生命周期函数导出
    • 打包工具配置更改
  2. 侵入型强其实说的就是第三点,更改打包工具的配置,使用 single-spa 接入微应用需要将微应用整个打包成一个 JS 文件,发布到静态资源服务器,然后在主,应用中配置该 JS 文件的地址告诉 single-spa 去这个地址加载微应用。不说其它的,就现在这个改动就存在很大的问题,将整个微应用打包成一个 JS 文件,常见的打包优化基本上都没了,比如:按需加载、首屏资源加载优化、css 独立打包等优化措施。项目发布以后出现了 bug ,修复之后需要更新上线,为了清除浏览器缓存带来的影响,一般文件名会带上 chunkcontent,微应用发布之后文件名都会发生变化,这时候还需要更新主应用中微应用配置,然后重新编译主应用然后发布,这套操作简直是不能忍受的,这也是   微前端框架 之 single-spa 从入门到精通   这篇文章中示例项目中微应用发布时的环境配置选择 development 的原因。
  3. 样式隔离问题 single-spa 没有做这部分的工作。一个大型的系统会有很的微应用组成,怎么保证这些微应用之间的样式互不影响?微应用和主应用之间的样式互不影响?这时只能通过约定命名规范来实现,比如应用样式以自己的应用名称开头,以应用名构造一个独立的命名空间,这个方式新系统还好说,如果是一个已有的系统,这个改造工作量可不小。
  4. JS 隔离这部分工作 single-spa 也没有做。 JS 全局对象污染是一个很常见的现象,比如:微应用 A 在全局对象上添加了一个自己特有的属性,window.A,这时候切换到微应用 B,这时候如何保证  window  对象是干净的呢?
  5. 资源预加载这部分的工作 single-spa 更没做了,毕竟将微应用整个打包成一个 js 文件。现在有个需求,比如为了提高系统的用户体验,在第一个微应用挂载完成后,需要让浏览器在后台悄悄的加载其它微应用的静态资源,这个怎么实现呢?
  6. 应用间通信这部分工作 single-spa 没做,它只在注册微应用时给微应用注入一些状态信息,后续就不管了,没有任何通信的手段,只能用户自己去实现

import-html-entry

qiankun  框架为了解决  JS Entry  的问题,于是采用了  HTML Entry  的方式,让用户接入微应用就像使用  iframe  一样简单。通过  http  请求加载指定地址的首屏内容即  html  页面,然后解析这个  html  模版得到  template, scripts , entry, styles,然后远程加载  styles  中的样式内容,将  template  模版中注释掉的  link  标签替换为相应的  style  元素。然后向外暴露一个  Promise  对象。

qiankun  就用了这个对象中的  template、assetPublicPath  和  execScripts  三项,将  template  通过  DOM  操作添加到主应用中,执行  execScripts  方法得到微应用导出的生命周期方法,并且还顺便解决了  JS  全局污染的问题,因为执行  execScripts  方法的时候可以通过  proxy  参数指定  JS  的执行上下文。