了解微前端

了解微前端

作为前端开发人员,这些年来,您一直在开发整体程序,即使您已经知道这是一个坏习惯。 您将代码划分为组件,在package.json中使用了require或import并定义了npm包,或者将sub git存储库安装到了项目中,但最终还是建立了一个整体。 现在该进行更改了。

为什么您的代码是一个整体?

本质上,所有前端应用程序都是单片应用程序,但已经实现了微型前端的应用程序除外。 原因是如果您正在使用React库进行开发,并且如果您有两个团队都应该使用相同的React库,并且两个团队在部署时应该保持同步,并且在代码合并期间始终会发生冲突。 它们没有完全分开,很可能它们维护相同的存储库并具有相同的构建系统。 单一应用程序的出口被表述为微服务。 但这是后端的!

什么是微服务?

通常,对微服务的最简单的解释是,它是一种开发技术,允许开发人员针对平台的不同部分进行独立部署而不会损害其他部分。 独立部署的能力使他们能够构建隔离的或松散耦合的服务。 为了使该体系结构更稳定,需要遵循一些规则,这些规则可以总结如下:每个服务应该只有一个任务,并且应该很小。 因此,负责此服务的团队应该很小。 关于团队规模和项目规模,詹姆斯·刘易斯和马丁·福勒在互联网上做出的最酷的解释之一如下:

在与微服务从业者的对话中,我们看到了各种规模的服务。 报告的最大尺寸遵循亚马逊的"两个比萨饼团队"的概念(即整个团队可以吃两个比萨饼),意思是最多可以吃十二个人。 在较小的规模上,我们看到了一组由六个人组成的团队支持六个人的服务的设置。

我创建了一个简单的草图,以直观地说明整体和微服务:

了解微前端

从上图中可以看出,微服务中的每个服务都是独立的应用程序,除了UI。 用户界面仍然是一件! 当一个团队处理所有服务并且公司正在扩大规模时,Frontend团队将开始挣扎,无法跟上它的步伐,这就是此体系结构的瓶颈。

了解微前端

除了其瓶颈外,该体系结构还将导致一些组织问题。 假设公司正在成长,并将采用需要跨职能小团队的敏捷开发方法。 在这个常见的例子中,产品所有者自然会开始将故事定义为前端和后端任务,而跨职能团队将永远不再是真正的跨职能部门。 这将是一个浅气泡,看起来像敏捷的团队,但将在内部深处分离。 更重要的是,管理这样的团队将是一项艰巨的任务。 在每个计划中,都会有一个问题,即在sprint中是否有足够的前端任务或后端任务。 为了解决这里描述的所有问题以及许多其他问题,几年前,出现了微型前端的想法,并且很快开始流行起来。

微服务瓶颈问题的解决方案:微前端

该解决方案实际上非常明显,包含了多年用于后端服务的相同原理:将前端整体划分为小的UI片段。 但是UI与服务不是很相似,它是最终用户与产品之间的接口,它应该是一致且无缝的。 甚至在单页应用程序时代,整个应用程序都在客户端的浏览器上运行。 它们不再是简单的HTML文件,而是复杂的软件,可以达到非常复杂的水平。 现在我觉得有必要定义微前端:

Micro Frontends背后的想法是将网站或Web应用程序视为由独立团队拥有的功能的组合。 每个团队都有自己关心和专长的不同业务或任务领域。一个团队是跨职能的,并且从数据库到用户界面,端到端地开发其功能。 (micro-fontend.org)

根据到目前为止的经验,对于许多公司来说,直接采用上述架构确实很困难。 许多其他人承受着巨大的遗产负担,这使他们无法迁移到新架构。 因此,更灵活,更灵活,易于采用和安全迁移的中途解决方案至关重要。 在更详细地概述了体系结构之后,我将尝试提供对体系结构的一些见解,该体系结构正在确认上述提议并允许采用更灵活的方法。 在深入研究细节之前,我需要建立一些术语。

整体结构和一些术语

假设我们正在通过业务功能在垂直方向上划分整体应用程序结构。 我们将最终得到几个较小的应用程序,这些应用程序具有与整体应用程序相同的结构。 但是,如果我们在所有这些小型整体应用程序之上添加一个特殊的应用程序,则用户将与该新应用程序进行通信,它将把每个小型应用程序中的旧整体UI组合成一个整体。 这个新层可以称为拼接层,因为它从每个微服务获取生成的UI部件,并合并为最终用户的一个无缝UI,这将是微前端最直接的实现。

了解微前端

为了更好地理解,我将每个小型整体应用程序都称为微应用程序,因为它们都是独立的应用程序,而不仅仅是微服务,它们都具有UI部分,并且每个都代表端到端业务功能。

众所周知,当今的前端生态系统具有高度的通用性,并且可能非常复杂。 因此,当需要将其用于实际产品时,这种简单的解决方案还不够。

要解决的问题

虽然本文只是一个想法,但我还是启动了Reddit主题来讨论这个想法。 感谢社区和他们的回应,我可以列出一些要解决的问题,我将尝试一一描述。

当我们拥有完全独立的独立微型应用程序时,如何创建无缝和一致的UI体验?

好的,这个问题没有灵丹妙药,但是其中一个想法是创建一个共享的UI库,它也是一个独立的微应用程序。 这样,所有其他微型应用程序都将依赖于共享的UI库微型应用程序。 在这种情况下,我们只是创建了一个共享依赖项,并且取消了独立微型应用程序的想法。

另一个想法是在:root级别共享CSS自定义变量。 该解决方案的优点是可以在应用程序之间进行全局可配置的主题。

或者,我们可能只是在应用程序团队之间共享一些SASS变量和mixins。 这种方法的缺点是UI元素的重复实现,并且应该为所有微型应用程序始终检查和验证相似元素的设计完整性。

我们如何确保一个团队没有覆盖另一个团队编写的CSS?

一种解决方案是通过由微型应用程序名称精心选择的CSS选择器名称进行CSS范围界定。 通过将此作用域任务放到缝合层将减少开发开销,但会增加缝合层的责任。

另一个解决方案是强制每个微型应用程序都是自定义Web组件。 该解决方案的优点是浏览器可以进行范围界定,但要付出一定的代价:使用影子DOM进行服务器端渲染几乎是不可能的。 此外,还没有100%浏览器支持自定义元素,特别是如果您必须支持IE。

我们应该如何在微型应用程序之间共享全球信息?

这个问题指出了与此主题相关的最令人关注的问题,但是解决方案非常简单:HTML 5具有相当强大的功能,大多数前端开发人员都不知道。 例如,自定义事件就是其中之一,它是在微应用程序中共享信息的解决方案。

或者,任何共享的pub-sub实现或T39可观察的实现都可以解决问题。 如果我们想要一个更复杂的全局状态处理程序,我们可以实现一个共享的微型Redux,这样我们就可以实现更多的响应式架构。

如果所有微型应用程序都是独立应用程序,我们如何进行客户端路由?

这个问题取决于设计的每个实现。 所有主要的现代框架都通过使用浏览器历史记录状态在客户端提供了强大的路由机制。 问题是哪个应用程序负责路由以及何时路由。

我当前的实用方法是创建一个共享客户端路由器,该路由器仅从顶层路由负责,其余的则属于各自的微型应用程序。 假设我们有一个/ content /:id路由定义。 共享路由器将解析/ content部分,并将解析的路由传递到ContentMicroApp。 ContentMicroApp是一个独立的服务器,将仅使用/:id进行调用。

我们必须确保具有服务器端渲染,但是微前端是否可以实现?

服务器端渲染是一个棘手的问题。 如果您正在考虑使用iframe来缝制微型应用程序,那么请忽略服务器端渲染。 同样,用于拼接任务的Web组件并不比iframe强大。 但是,如果每个微型应用程序都能在服务器端呈现其内容,则拼接层将仅负责在服务器端连接HTML片段。

与遗留环境的集成至关重要! 但是如何?

为了集成遗留系统,我想描述一下我自己称为"渐进式入侵"的策略。

首先,我们必须实现拼接层,它应该具有透明代理的功能。 然后,我们可以通过声明通配符路由将旧系统定义为微型应用程序:LegacyMicroApp。 由于我们还没有其他微型应用程序,因此所有流量都将到达缝合层,并透明地代理到旧系统。

下一步将是我们的第一个渐进式入侵运动:我们将通过删除主导航并将其替换为依赖项,从LegacyMicroApp中获取一些帮助。 这种依赖关系将是使用闪亮的新技术实现的微型应用程序:NavigationMicroApp。

现在,拼接层会将每条路线解析为LegacyMicroApp,并将其依赖项解析为NavigationMicroApp,并通过将这两者连接起来为它们提供服务。

然后,通过遵循与主导航相同的模式,页脚将迎来下一个叮咬。

然后,我们将继续从LegacyMicroApp进行类似的小尝试,直到不再留下任何东西为止。

如何协调客户端,这样我们就不必每次都重新加载页面了?

好的,拼接层可以解决服务器端的问题,而不能解决客户端的问题。 在客户端,将已经粘合的片段作为无缝HTML加载后,我们不需要每次都在URL更改时加载所有部分。 因此,我们必须具有某种异步加载片段的机制。 但是问题是,这些片段可能具有某些依赖关系,并且这些依赖关系需要在客户端进行解析。 这意味着微前端解决方案应该提供一种加载微应用程序的机制,以及某种依赖注入的机制。



根据上述问题和可能的解决方案,我可以总结以下主题下的所有内容:

客户端

· 编排

· 路由

· 隔离微应用

· 应用到应用的交流

· 微型应用程序用户界面之间的一致性

服务器端

· 服务器端渲染

· 路由

· 依赖管理

灵活而强大而又简单的架构

了解微前端

因此,值得一直等待本文! 微型前端架构的基本元素和要求终于开始展现自己!

在这些要求和关注的指导下,我开始开发一种名为microfe的解决方案。 在这里,我将以抽象的方式强调其主要组成部分,以描述该项目的体系结构目标。

从客户端开始很容易,它具有三个独立的主干结构:AppsManager,Loader,Router和一个额外的MicroAppStore。

了解微前端

AppsManager

AppsManager是客户端微应用程序编排的核心。 AppsManager的主要功能是创建依赖关系树。 解决了微型应用程序的所有依赖关系后,它将实例化微型应用程序。

装载机

客户端微应用程序编排的另一个重要部分是Loader。 加载程序的责任是从服务器端获取未解析的微型应用程序。

路由器

为了解决客户端路由,我将路由器引入了microfe。 与普通的客户端路由器不同,microfe路由器功能有限,它不能解析页面,但可以解析微应用程序。 假设我们有一个URL / content / detail / 13和一个ContentMicroApp。 在这种情况下,microfe路由器将解析URL直至/ content / *,并将调用ContentMicroApp / detail / 13 URL部分。

MicroAppStore

为了解决微型应用程序到微型应用程序的客户端通信,我将MicroAppStore引入了microfe。 它具有Redux库的相似功能,但有一个区别:它对异步数据结构更改和reducer声明具有弹性。



服务器端部分的实现可能会稍微复杂一些,但结构也会更简单。 它仅由两个主要部分StitchingServer和许多MicroAppServer组成。

MicroAppServer

了解微前端

MicroAppServer的最低限度的功能可以概括为init和服务。

在启动MicroAppServer时,它应该做的第一件事就是使用微应用程序声明调用SticthingServer注册端点,该声明定义了MicroAppServer的微应用程序依赖项,类型和URL架构。 我认为没有必要提及服务功能,因为它没有什么特别之处。

拼接服务器

了解微前端

StitchingServer为MicroAppServer提供注册端点。 当MicroAppServer将自己注册到StichingServer时,StichingServer会记录MicroAppServer的声明。

稍后StitchingServer使用声明从请求的URL解析MicroAppServer。

解决MicroAppServer及其所有依赖关系后,CSS,JS和HTML中的所有相对路径都将以相关的MicroAppServer公共URL开头。 另一步骤是在CSS选择器前添加MicroAppServer的唯一标识符,以防止客户端上的微型应用程序之间发生冲突。

然后,StitchingServer的主要职责就出现了:从所有收集的部分组成并返回一个无缝的HTML页面。

一瞥其他实现

甚至在2016年被称为微型前端之前,许多大公司都在试图解决类似的问题,例如Facebook的BigPipe。 如今,这一想法正在蓬勃发展。 不同规模的公司对这个主题很感兴趣,并为此花费了时间和金钱。 例如,Zalando开源了其解决方案,称为Project Mosaic。 我可以说microfe和Project Mosaic正在遵循相似的方法,但存在一些重大差异。 尽管microfe包含完整的去中心化路径定义以为每个微型应用程序提供更大的独立性,但Project Mosaic还是更倾向于为每个路径使用集中式路径定义和布局定义。 通过这种方式,Project Mosaic允许轻松地进行A / B测试以及动态生成动态布局。

还有其他一些方法可以解决这个问题,例如使用iframes作为拼接层,这显然不在服务器端,而在客户端。 这是一个非常简单的解决方案,不需要太多的服务器结构和DevOps的参与。 该工作只能由前端团队完成,因此它减轻了公司的组织负担,并且降低了成本。

已经有一个称为Single-Spa的框架。 该项目依赖于每个应用程序的命名约定来解析和加载微型应用程序。 容易掌握想法并遵循模式。 因此,这可以是在您自己的本地环境中试验该想法的很好的初始介绍。 但是该项目的缺点是您必须以特定的方式构建每个微型应用程序,以便它们可以很好地与框架配合使用。

最后的想法

我相信,微前端主题将得到更频繁的讨论。 如果这个话题能够引起越来越多公司的注意,那么它将成为大型团队事实上的发展方式。 在不久的将来,对于任何前端开发人员来说,掌握有关此体系结构的一些见解和经验都将是非常有益的。


(本文翻译自Öner Zafer的文章《Understanding Micro Frontends》,参考:https://medium.com/hackernoon/understanding-micro-frontends-b1c11585a297)


分享到:


相關文章: