随着咱们中后盾零碎的简单,往往会遇到多个团队独立保护的子利用接入对立的主利用中,这些子利用往往独立开发、独立部署、彼此齐全解耦,这时候平常的繁多利用无奈满足业务的增长需要。而微前端便是用来解决随着工夫的推移业务复杂度的晋升,某个单利用演变为难以保护的“巨石利用”。
这便文章并不是一个源码解析以及上手教程的文章,我心愿从一个宏观的角度介绍下微前端并且简略聊一下微前端在咱们当初我的项目中的一些思考。
先聊聊背景
我始终认为抛离业务的技术改造都是没有太大价值并且很难走远的。这里我先简略介绍下我对目前我的项目所做的一个架构演变以及一些简略思考。我目前所处一个大型的 B 端我的项目团队,零碎依据业务域划分的子利用有几十个,零碎 PV 百万 +,所以在这样一个宏大的零碎中咱们的零碎架构也经验了以下一些变动。
模版架构
在我刚退出团队的时候,咱们的零碎还是一个前后端未齐全拆散的架构,模版提供了一个入口挂载根节点,前端在根节点上渲染 React / Vue 利用。
不难发现这样的架构存在肯定的弊病:
- 后端解析模版,挂载模版;
- 后端管控路由,前端失去了对路由的掌控权,并且多个团队路由规定管控较难;
- 每一次前端公布须要先公布动态资源再公布模版,公布繁琐容易出错;
- 这样的开发方式相对来说较为古老,对于喜爱捣鼓新事物的前端来说很难激发激情;
然而值得庆幸的是,这时候咱们的零碎曾经有肯定的分治思维了,主利用(这个时候应该说是 layout 层)和子利用独自挂载在不同的模版片段上,这也为前面的 iframe 和微前端革新缩小了不少工作量
其实,这样的架构也有肯定微前端的影子:)。
iframe 架构
前面随着后端微服务化的转型,后端曾经不去关怀路由的管控和页面的挂载,转而提供更加原子化的微服务。而对咱们前端来说:
- 须要不依赖后端模版;
- 须要管控路由并制订对立的路由规定;
- 奴才利用的沙箱隔离;
- 尽量对子业务的改变做到最小化,很多业务包袱很重;
- 疾速落地并实现高可用(没方法,开发工夫永远是一个战胜很多选项的因素 …);
然而随着 iframe 架构的落地以及后续迭代的进行,咱们也发现了 iframe 计划的一些弊病:
- 通信形式简略,简略的 postmessage API 并不能满足业务的需要;
- 款式割裂,iframe 会导致诸如 Dialog 这样子的全局蒙层仅在 ifame 区块内展现,使咱们零碎更像是“拼凑”进去的;
- 性能瓶颈,路由的切换会导致 iframe 内子利用的从新加载,性能堪忧;
- 跨域问题,chrome80 的 samesite 策略会导致 iframe 计划的跨域 cookie 无奈带给后端;
微前端架构
最初在往年中旬的时候我这边将 iframe 架构降级到了微前端 + iframe 并存的架构,并开发落地了一系列微前端相干的开发工具链(喜大普奔 …)。
so,为什么不是 iframe?
在我看来,微前端是一个思维,是一种开发模式和架构的演变,诸如 qiankun、icestark 等框架也仅是微前端实现的落地,正当的 iframe 实现未尝不算是一种微前端实现的落地。咱们原来的 iframe 架构设计肯定水平上也算是一种微前端思维,并且在我看来,iframe 对于这种跨团队的中后盾巨无霸我的项目仍然有着人造的劣势,理由如下:
- 框架无关:iframe 只加载部署完利用链接;
- 独立沙箱:iframe 领有浏览器的独立沙箱,子利用和主利用齐全不必思考 js & css 净化问题;
- 开发简略:仅仅一个 iframe 标签;
然而,与之而来的便是 iframe 的一些痛点:
- UI 体验不好:iframe 仅在制订的渲染块内渲染,而子利用的一些相似于带遮罩层的 Modal 等全局的 UI 组件只会在 iframe 内出现;
- 通信艰难:iframe 弱小的沙箱机制带来的副作用就是父子利用通信艰难,仅仅一个 postmessage API,跨域 cookie、Promise 等等都难以实现;
- 路由失落:子利用的 url 扭转无奈及时同步父利用,随着页面的刷新,子利用的路由状态失落;
- 加载工夫长:每次子利用进入都是一次浏览器上下文重建、资源从新加载的过程;
只管以上这些痛点或多或少的配合着一些 hack 的工具以及开发标准都有肯定的解决方案,然而有更好的抉择为什么不尝试呢:)
那么,什么是微前端?
这里我不去讲概念,情理大家都懂,概念一搜全都是。例如微前端很官网的诠释:
Techniques, strategies and recipes for building a modern web app with multiple teams that can ship features independently
就像巨石利用并不是欲速不达的,接下来我来通过一个巨石利用的演变来向大家介绍我了解的微前端。
单个页面
起初咱们的零碎可能仅有一个业务模块。路由硬编码在我的项目里,layout 层和业务子系统也写在一起。
多个页面
随着业务的增长,咱们的零碎接入了更多的业务模块,这个时候其实通过肯定的路由配置和多页的配置,我的项目也还算是没太大问题。
然而这个时候须要引起警惕,如果再接入了更多的业务模块还停留在以后的模式下,我的项目该怎么保护?
更多的页面?巨石利用!
随着业务更进一步的增长,接入的业务模块越来越多,不仅咱们以导航维度裁减的子利用增多,甚至诸如首页这样子的页面上也会有归属于多个业务域的区块。总结起来就会分为两类场景:
- 单实例:一个或多个页面对应一个子利用,同一时刻仅有一个子利用渲染展现;
- 多实例:一个页面蕴含多个子业务利用区块,同一时候有多个实例渲染展现;
这时如果没有很好的解决和子系统的拆分,那么咱们的利用就会变为巨石利用 …
- 开发迭代并上线一个巨石利用比上线多个子利用要蛋疼的多 …
- 多人(多团队)保护一个我的项目,你永远不晓得他人做了啥或者将要做啥 …
- 往往这样子的利用,大家都是做加法而不去做减法,使得我的项目越来越大,无用代码越来越多 …
微前端,分而治之!
这时候咱们往往将零碎依据业务域的划分拆分成不同的子利用,而承载这些子利用的 layout 层咱们拆分为主利用,各个子利用独立开发独立公布,并且由不同的业务团队保护,以此来解决简单的单体利用带来的各种开发保护问题。
能够看出,微前端便是采取 分治 的思维来防止单体利用演变成巨石利用的。
在我看来,在微前端的思维中,重点强调了几点:
- 独立性:微前端的主利用以及各个子利用独立开发、独立部署,并且在肯定水平上微前端子利用能够独立于主利用独自运行;
- 沙箱隔离:子利用有本人独自的运行时,各个子利用之间的状态不被共享;
- 框架无关:子利用齐全能够采取不同的框架进行开发,因为现有微前端框架实现中,主利用仅是加载子利用构建后的 bundle;
咱们的抉择
当初市面上的微前端框架有很多,例如阿里外部就有 icestack、qiankun 两大比拟成熟的开源微前端框架,以及社区上 singleSPA 等。那么咱们该如何抉择适宜咱们我的项目的微前端框架呢,这里我简略列举了我在抉择微前端框架时候的一些思考:
- 改变老本:任何业务团队都不能逃避这个话题,你怎么压服产品和老板须要这么长时间的技术改造(还存在肯定危险)、你怎么压服子利用方配合革新(置信我,子利用方不会违心去做 > 1 天革新的 …);
- 沙箱隔离:这个就不多说了,很多子利用会集成本人的埋点 & 监控体系,这样的体系往往会挂载或者劫持全局变量的;
- 路由不变性:在咱们 iframe 架构中,曾经有一套比较完善的路由规定,那么如何保障路由不变的前提上来做架构降级呢?
- 通信不变性:同上,在咱们的 iframe 架构中,曾经有一套比拟成熟的通信工具,那么能不能在保障 API 不变的前提下实现微前端的通信呢?或者罗唆微前端能够服用 iframe 的通信工具?
- 兼容 iframe:这么宏大的零碎不是一下子就迁徙到微前端的,并且咱们也不打算摈弃 iframe 架构(不肯能全副业务都迁徙的 …)。那么,如何保障两套架构的共存?更进一步,如何保障两套架构共存而后还能共享一套路由规定?
- 灰度管制:子利用的大版本公布往往会随同着灰度管制,那么如何保障微前端接入后也能有残缺的灰度流程?是做一个版本管控的工具还是间接应用 htmlEntry?
- “远古”利用接入:远古利用放弃 iframe 嵌入就最好了,那么咱们能不能贪一点也能反对“远古巨龙”的丝滑接入呢?
最初,联合下面的一些思考以及咱们当初的零碎架构,我抉择了 qiankun 来落地咱们的微前端计划。并且为了保障微前端接入以及版本管控的便捷,咱们
结语
以上便是我在做微前端革新时候联合业务零碎的一些思考,如果有不对的中央欢送斧正。之后我也会输入 qiankun 的源码解析以及我所做的一些微前端工具的原理剖析等文章(撒花 …)。