简单的说,微前端架构是从微服务理念扩展而来的,一个适用于前端的微服务架构。
微服务
架构,通常拿来对比的架构是单体软件
架构,单体软件
存在以下几个问题:
- 所有功能耦合在一起,互相影响,最终难以管理
- 哪怕只修改一行代码,整个软件就要重新构建和部署,成本非常高
- 不可能每个功能单独开发和测试,只能整体开发和测试,导致必须采用瀑布式开发模型
因此开始出现将单体软件拆成一个个功能单元服务
+通讯协议
组成,这种叫面向服务
(service-oriented architecture,简称 SOA)架构,也是微服务的雏形。
因此微服务
架构的等于面向服务
架构,它有多种实现方案,其中最佳实践是基于Docker容器实现的。
微服务的几大特性:
- 敏捷性, 可快速迭代自己的微服务
- 弹性部署,快速持续集成与部署,服务独立性增加了应用程序应对故障的弹性
- 技术自由,可以自由选择最佳工具来解决他们的具体问题
- 可重复使用的代码,可以将专为某项功能编写的服务可以用作另一项功能的构建块
Ok,微服务了解到这里基本上就有大概的认知,微服务当然不只是这些,还有一些其他技术点,如:服务发现、事件传播等。
先来看几个图:
组件 VS 微前端
我们从另外一个角度的去看待微前端,假设将微前端看做组件,是不是就好理解多了,只不过这个组件有点大,功能比较齐全,没有对外提供参数配置。
但是从两者的实际应用场景来说,还是有很多不同的地方,具体如下:
- 从应用场景来看,组件是不可运行,被调用的,是应用中一部分,而微前端是完整可运行的一个应用
- 从技术上来看,组件是基于某个框架实现的,而微前端应用不依赖任何框架,但是微前端架构会依赖某个框架实现
总的来说
微前端
架构,就是把复杂问题简单化,每个微前端
项目都只需要关心自己的事情。因此微前端
架构的核心思维如下:
技术不可知
,每个微前端
都应该选择自己的技术栈和技术进化路线,而不是和其他团队保持一致,同时架构师应该考虑的是如何高效的提供可复用的WebComponent会成为核心问题环境隔离
,微前端
架构中每个子项目不共享运行时环境,即是:不依赖共享状态或全局变量,同时也可以通过命名规范(如:前缀)或命名空间,去隔离每个微前端应用原生API优先
,使用 用于通信的原生浏览器事件机制 ,而不是自己构建一个PubSub系统独立性
,微前端
架构中每个子项目是完整的,可以独立运行、独立开发、独立部署高可用
,微前端
架构是高可用的,即使某个子应用异常也不会影响其他子应用的访问
以上就是要实现微前端
架构所需要考虑的点,同时也是架构中的核心思维。
说说其缺点:
微前端架构在上面描述了很多优势,但是如果没做好架构设计,它也可能会带来一些问题,因此我们需要提前了解微前端架构
可能会带来的缺陷:
- 增加运维成本,因为由原本只需要发布一个应用,变成需要发布N个应用
- 拆分粒度越小,架构越复杂,开发维护成本越高
- 微前端支持不同技术栈,那么也带来了不同技术栈带来技术栈混乱的风险,同时也提高了开发维护成本
- 微前端架构本身就是将项目完全独立,可能导致部分公共代码无法通用
- 还有一些其他问题,如:当采用某类微前端框架增加开发成本等
上面这些问题,在项目是否要用微前端架构都需要考虑的事情,
那么在项目要实施微前端
架构,主要有几个工作项:
- 首先,就是需要搞清楚如何将项目拆分一个个微前端子项目
- 其次,选型,采用哪种微前端框架去实施
- 最后,使用渐进式方案去实施,而不是一口气全切换,如果是新项目直接采用微前端架构,那么这里推荐采用Monorepo大仓+微前端,这里会让极大降低项目的管理成本。
1、如何拆分
微前端架构主要工作就是拆分,那么问题来了,我们应该依据什么样的标准去拆分呢?我们大体可以从下几点去考虑:
- 第一,拆分条件,项目是否适合微前端架构
- 第二,拆分原则,项目拆分时候需要遵循的设计原则
- 第三,拆分方法,项目拆分可以依据哪些因素进行拆分
2、拆分条件
我们要对项目进行微前端架构设计的时候,我们应该从下面几方面去考虑是否适合:
- 是否有快速迭代的需求,如果有快速迭代需求,则表示业务需要快速响应,那么采用微前端架构去拆分,不仅支持快速迭代,还支持业务快速试错
- 是否有代码提交出现大量冲突,如果有,则表示代码管理成本较高,微前端架构可以降低项目的管理成本
- 是否小功能需要等待大版本的场景,如果有,则表示小功能会影响到大版本的功能,这个时候微前端架构的
独立发布
特性,可随时回滚,风险变小,时间变短,影响面小,从而降低大版本发布延期风险
从上面几个方面,我们可以很清晰的判断当前项目是否需要做微前端架构调整,只有这个时候,微前端的拆分才是有确定收益的,增加的运维成本才是值得的。
3、拆分原则
当我们面对需要拆分微前端的时候,以下几个原则可以作为参考:
- 单一职责原则,每个微前端只需关心自己的业务规则,确保职责单一,避免职责交叉
- 服务自治原则,每个微前端的开发,必须拥有开发、测试、运维、部署等整个过程,表示该应用可以独立运行而不需要依赖其他应用
- 持续演进原则,单体架构向微服务架构拆分过程中,无法做到一蹴而就,应逐步拆分细化,持续演进,避免微服务数量的瞬间爆炸性增长
- 服务粒度适中,先粗后细的原则,再按照拆分条件判断粗粒度的微前端是否需要拆分
- 避免循环依赖,循环依赖的情况会导致微前端在迭代发布的时候不知道优先发布哪个,在拆分的时候需要考虑,针对依赖部分进行下沉,拆分成公共模块
- 横向拆分原则,拆分微前端应该按照依赖层次的横向去拆,而不是纵向拆分,因为拆分越深,维护成本越高
4、拆分方法
以上两个主要针对拆分的假设条件,当真正去拆分操作的时候,我们应当从这些方面去入手:
- 按照业务领域,参考领域模型,将同类业务归为同一个微前端,按照单一职责原则、功能完整性进行拆分
- 按照组织架构,应尽量避免对组织架构和团队的调整,避免由于功能的重新划分,而增加大量且不必要的团队之间的沟通成本
- 按照技术栈,简单点说React的技术栈放一个微前端,Vue的技术栈放另外一个微前端
- 按需求迭代频率,将迭代频率高的放在一个微前端,频率低放在另外一个微前端
学会了拆分方法,里面的优先级应该有大概排序,业务领域 > 组织架构 > 技术栈 > 需求迭代频率,我推荐的做法如下:
- 先按照业务领域去拆分
- 拆分的粒度不够,还要再拆分就按照组织结构再拆分
- 再往下,就是按照技术栈拆分
- 再往下,就是需求迭代频率
微前端框架
了解完如何拆分,那么接下来就是对微前端架构实现的框架进行选型,下面是我从网上收集目前市场主流的几大微前端框架:
- single-spa,将多个单页面应用聚合为一个整体应用的 JavaScript 微前端框架
- qiankun,基于single-spa,能更简单、无痛构建可用微前端架构的框架
- 无界,基于iframe,实现路由同步机制的微前端架构框架
- micro-app,借鉴WebComponent思想,结合自定义的ShadowDom,将微前端封装成一个类WebComponent组件的微前端框架
- webpack 模块联邦,在webpack构建时候加载远程应用而实现的微前端架构方案
以上,就是目前实现微前端架构的主流框架,当然每个框架都自己的优缺点,我们在选型的时候主要还是通过以下几点去判断是否适合:
- 对现有项目是否需要改造,改造成本多少
- 是否有学习成本,学习成本有多复杂
- 未来是否足够的扩展性
- 团队内是否有熟悉、精通该选型的人,否则遇到问题,容易入坑
- 项目维护的情况,issue 是否有响应,迭代是否在正常进行
到了这里,本篇介绍微前端架构基本上就结束了,虽然很多理论知识,但是我们可以再次回顾一下,总结一下要点:
- 微前端架构源自微服务架构,两者主要都是为了解决巨石应用的痛点,迭代慢、开发复杂
- 微前端架构拆分需要注意几个点:拆分条件、拆分原则和拆分方法
- 微前端架构主流框架:single-spa、qiankun、无界、micro-app、webpack 模块联邦等