从微前端到single-spa的简单解析

1,082 阅读5分钟

什么是微前端?

当你项目没有足够大的时候,你不需要它甚至可以说不需要了解它。

微前端的出现,解决了两个问题,第一,一个庞大的前端的项目,当里面的子模块需要独立部署,这样就不会因为子模块的部署或者出错,导致整个应用都不可用, 第二,当你有历史项目要维护,例如有个例如项目是angular4.x写的,但是估计现在你要找到会这独门绝技的人如凤毛麟角,你希望用你熟悉的技术栈去添加新功能新模块

只有在这时,微前端就像驾着七彩祥云来到了你的面前。微前端听起来很像后端的微服务,但其实又本质上的不同。微前端的所有操作都在浏览器的一个tab里面,不同模块之间可以采用不同的框架去实现,微前端像一个中控台,负责去精确地调度不同模块之间的加载、卸载等,让他们和平地相处在同一个页面里面,互不干扰。

浅谈single-spa

single-spa提供了一系列规范,或者是生命周期,让不同的框架去按照这些规范,提供合规的模板。例如react提供了single-spa-react模块,里面实现了主要的三个生命周期,bootstrap、mount、unmount,实例化的目标,注册到root-config上面后属于一个application。

这里再讲讲什么是root-config、application,root-config属于一个总控的配置,上面所有模块的配置,而每个模块属于一个application,需要在root-config上面调用registerApplication进行注册,registerApplication(name, loadImpl, activefn),name是模块的名字,loadImpl必须是返回一个promise或者async方法,让single-spa在合适的时候去加载模块代码,activefn可以认为是激活函数,当路由变化的时候,single-spa调用activefn,通过返回值来决定当前模块需要进行卸载还是mount等等,例如在下面中,注册了kc应用,激活条件比较简单,url上面有kc字眼就进行mount

下面我来看看效果,这是url上面没有kc的,注册的kc应用并没有挂载

当kc出现在url时,注册的kc应用就挂载了
其实在single-spa中,还有第三种配置,就是parcel,用于跨模块间实现组件的复用,但是需要由调用者手动去管理parcel的挂载以及卸载等,这是缺点,所以只有我们真的需要复用组件以及存在多个框架的时候,才需要parcel,需要注意的是,parcel与框架无关,你可以写个vue的parcel组件,然后让react应用去挂载mountParcel,或者manual手动是最大的缺点的吧。

前面说了当路由变化的时候,single-spa可以精确地调度模块。为什么可以做到这点呢?原因其实很简单,single-spa对路由进行hack了,数一数,一共做了三件事,

1、hack了pushState、replaceState方法,这样任意一个模块里面调用这两个方法,都会导致整个single-spa重新激活卸载各类application

2、hack了popState、pushState方法,当这两个方法触发时,交由single-spa去总控reroute
3、hack了addEventListener方法,在做了第二步之后,再进行addEventListener的hack,这样在子模块中监听popState、pushState的时间都不是第一时间的,只有single-spa确认应用确实加载之后才会触发,确保正确的路由加载成功了
4、不是只有三件事吗?没事的啦,数学不好,第三步中,我们hack了原生的addEventListener的,但是如果你还需要jq呢,所以再顺便hack了jq中的on和off方法,打完收工

通过这样的三板斧,single-spa牢牢地把各模块的加载控制在自己的手中,当然single-spa做的事情很多,要先进行应用的卸载、然后进行应用的加载,还要对加载时间有个timeout的阀值管理等等,真的那种当爹又当娘的赶脚。

可能看到这,可以理解single-spa如何进行模块的加载,还是没看到独立部署啊?如果你仔细品一品,上面kc的应用,不是部署在root-coifig的9000端口那里的,而是部署在8080,9000只是负责加载kc,这样8080的kc应用下线、部署甚至加载超时,9000会触发加载时间超时事件,而不会影响其他模块的加载,这就是微前端的精髓了!有了微前端,我们就可以大胆地上线部署我们自己的模块了,而且也可以不断拆分我们的项目,就算我们的项目可能只有一个技术栈,这对于一个大型项目来说,简直是苦尽甘来啊。

写在最后

single-spa确实做了很多,可在css隔离和js沙箱还有state管理等方面,还是需要二次封装,但这并不影响single-spa的伟大,起码它走了微前端的第一步。

再说一句,为什么是简单解析,因为这都属于简单系列的文章,起个引起,权当学习笔记和个人见解,没有进行强校对,有鄙陋欢迎指出,认真系列或者在未来某天会开篇吧(qoute from: one punch),让我们拭目以待