Microfronts:我们在说什么?

这些年来,您(前端开发人员)编写了巨著,尽管您知道这是一个坏习惯。 您将代码划分为组件,在package.json中使用了requireimport并定义了npm包,或者在项目中生成了git仓库,但是无论如何,您还是编写了一个整体。
现在该换位置了。

为什么您的代码可以视为整体?


从本质上讲,所有前端应用程序都是单片的-除了实现微前端的应用程序之外。 原因是您正在使用React库进行开发,并且有两个团队在做这项工作。 两者都应该使用相同版本的React,并且彼此保持最新状态,这意味着它们将始终解决与代码合并的冲突。 它们在代码库中并不完全彼此独立。 他们可能都使用相同的存储库和一个构建系统。 微服务可以节省整体应用程序! 但是,如何呢? 毕竟,它们是用于后端的! *令人惊讶的惊喜*

什么是微服务?


简而言之,微服务是一种开发技术,允许开发人员针对平台的不同部分进行功能(发布)的独立交付,同时发布不会相互破坏。 独立的耗材使他们能够收集隔离的或松散耦合的服务。 有一些规则可以使此体系结构更强大。 简而言之,它们可以定义如下:每个服务应该很小并且只能执行一项任务。 因此,从事此工作的团队也应该很小。 詹姆斯·刘易斯和马丁·福勒解释说,一个项目和一个团队有多大?

与微服务进行交互的开发人员会命名不同的大小。 其中最大的一个满足了亚马逊的两个比萨饼团队战略-最多不超过10-12人。 反向杆-5至6人的团队,每个团队支持一项服务。

这是说明整体服务和微服务之间的区别的图:



从图中可以看出,微服务系统中的每个服务都是一个独立的应用程序,除了UI之外-它仍然是一个整体! 如果所有服务都由一个团队支持,则随着公司的发展,风险很大,前端团队将无法跟上用户界面。 这是此体系结构的漏洞。



体系结构会带来组织问题。 假设公司已经发展壮大并采用了灵活的开发方法(我说的是敏捷)。 他们需要小型跨职能团队。 当然,在我们的抽象示例中,管理人员将开始分离前端和后端的任务,并且跨职能团队将不会真正实现跨职能。 而且所有的努力都是徒劳的:团队看起来可能很灵活,但实际上会产生很大的分歧。 管理这样的团队不是为了胆小。 在每次会议上都会有一个问题:sprint中是否有足够的前端任务,是否有足够的后端任务? 为了解决这些问题以及其他许多问题,几年前,出现了Microfront的想法,该想法迅速普及。

问题的解决方案:微型战线


该解决方案看起来非常明显,因为类似的原理早已在后端服务的工作中成功应用:将整体式前端拆分为小的UI片段。 但是,UI与服务并不十分相似-它是最终用户与产品之间的接口,必须经过深思熟虑和系统化。 而且,在单页面应用程序时代,整个应用程序是通过客户端上的浏览器启动的。 这些不再是简单的HTML文件,它们是可以包含各种UI和业务逻辑的复杂组件。 现在,也许有必要定义微观前沿。

Microfront的原理:网站或Web应用程序的呈现是一独立团队负责的功能。 每个团队都有自己的使命,专业领域。 团队具有跨职能并不断发展
整个周期 -从数据库到用户界面( micro-fontend.org )。

我目前的经验表明,对于许多公司而言,可能难以接受上面提出的架构。 对于其他人,旧代码的负担不允许过渡到新架构。 因此,需要一种更平滑,更轻松和更可靠的迁移方式。 在详细研究了体系结构之后,我将尝试提出解决问题的愿景。 在研究细节之前,请先熟悉术语。

总体结构和更多术语

想象一下,我们按业务功能垂直划分了单片应用程序的结构。 我们将获得几个具有与整体应用程序相同结构的较小应用程序。 但是,如果我们在这些小型整体应用程序之上添加一个特殊的应用程序,则用户将与其进行交互。 反过来,它将集成那些小型应用程序的UI。 我们称此级别为链接,因为它采用了每个微服务的UI元素并将它们组合到一个接口中-​​这是微前端最直接的实现。 *真诚的钦佩*



更清楚地说,在下文中,我将每个小型整体应用程序称为应用程序,因为它们不仅是微服务,而且是独立的应用程序-每个应用程序都有UI元素,并且每个代表完整的业务功能。 如您所知,当今的前端生态系统非常多样化,并且可能非常复杂。 这种简单,明显的解决方案可能不适用于产品实施过程。

需要解决的问题


当这篇文章的想法诞生时,我在Reddit上发起了一个主题来讨论它。 感谢社区成员和他们的反馈,我可以列出需要解决的问题。

问题编号1:当我们有几个完全自治的微型应用程序时,可以通过UI实现一致且一致的行为

没有灵丹妙药,但是有一个想法可以创建一个通用的UI库,它也可以是一个独立的微型应用程序。 在这种情况下,所有其他微型应用程序都将依赖于此UI库。 这杀死了他们的独立性。

另一种选择是在根级别创建通用CSS变量 。 该解决方案的优势在于,我们为所有应用程序获得了全局自定义主题。

或者,我们可以使SASS变量和杂质对所有团队通用。 这种方法的缺点之一是UI元素的重复实现以及在所有微型应用程序中需要不断验证相似元素的设计。

问题2:确保一个小组不重写另一小组的CSS

首先,您可以使用由微应用程序名称组成的选择器来限制CSS的范围。 通过在中间层设置此限制,可以减少总体开发时间,但是同时,中间层的责任也会增加。

其次,您可以使每个微型应用程序成为一个自定义Web组件 。 这种方法的优点是浏览器可以处理该限制。 但是,所有东西都有代价:使用Shadow DOM,几乎不可能在服务器端进行渲染。 此外, 浏览器不 100% 支持自定义元素-特别是在需要IE支持的情况下。

问题3:使全局信息对不同的微应用程序通用

这个问题是最常见的问题之一,但是很容易解决。 HTML5具有非常强大的功能,大多数前端开发人员几乎未开发。
这些功能之一是自定义事件,可让您使信息成为微应用程序所共有的。

pub-sub或T39实施也可能会有所帮助。 如果您需要更细微的全局状态处理程序,则可以实现一个小型的通用Redux-这将提供一个响应更快的体系结构。

问题4:如果所有微应用程序都是自治的,那么如何在客户端进行路由?

该问题的解决方案取决于实现方式。 所有主要的现代框架都具有使用浏览器历史记录状态的强大的客户端路由机制。 问题是哪个应用程序负责当前路由以及何时运行。

我的务实方法是创建一个通用的客户端路由器,仅负责顶层路由,其余的则由相应的微应用程序负责。 假设我们有一个路线定义/content/:id. 通用路由器将解决c /content ,并将解决的路由传递给ContentMicroApp。 ContentMicroApp是一个独立的服务器,只能使用/:id进行调用。

问题5:我们真的需要SSR(服务器端渲染)吗,使用微型前端时可能吗?

服务器端渲染并不容易。 如果您要使用iframe捆绑微应用程序,则无需考虑服务器端渲染。 同样,用于绑定的Web组件并不比iframe强。 但是,如果每个微型应用程序都能够呈现服务器端内容,则连接层将仅负责在服务器端组合HTML片段。

问题6: “需要与现有环境集成,例如空气! 怎么做?”

为了与现有系统集成,我想描述一下我的愿景,我称之为“ 逐步实施 ”。

首先,我们必须实现中间件层,使其具有透明代理服务器的功能。 之后,我们可以通过声明到它的特殊路径来将现有系统定义为微应用程序( LegacyMicroApp )。 由于我们还没有其他微型应用程序,因此达到连接级别的所有流量都将透明地代理到现有系统。

下一步是逐步实施。 我们将使用一小段LegacyMicroApp ,删除主导航,将其替换为依赖项。 这种依赖关系是使用全新的出色技术NavigationMicroApp实现的微型应用程序。

现在, LegacyMicroApp将通过NavigationMicroApp依赖项拦截所有路由,并在内部对其进行处理。

然后,以类似的方式,我们将重新制作页脚。

因此,我们将继续咬下去的LegacyMicroApp,直到它一无所有。

问题7:协调客户端,这样您不必每次都重新加载页面

中间件层解决了客户端方面的问题,但没有解决服务器端的问题。 在客户端,通过下载单个HTML,我们无法在更改URL时加载各个部分。 因此,我们需要一种异步加载片段的机制。 问题在于这些片段可能具有依赖关系,并且这些依赖关系需要能够在客户端进行解析。 这意味着微前端解决方案应该提供一种加载微应用程序和实现依赖注入的机制。

上面列出的问题可以合并为以下主题:

客户端

  • 编排
  • 路由选择
  • 微隔离
  • 应用程序交互
  • Unity UI微型应用程序

服务器端

  • 服务器渲染
  • 路由选择
  • 依赖管理

灵活而强大但结构简单


为此,值得忍受本文开头! 微前端架构的主要元素和要求终于开始出现;)

在需求和关注的指导下,我开始开发一种称为microfe的解决方案。 *期望得到反馈*
在这里,我将概述该项目的体系结构,简要描述其主要组成部分。

最简单的开始方法是从客户端开始,它具有三个独立的主要结构: AppsManager,Loader,Router以及一个附加的MicroAppStore



AppsManager
AppsManager是客户端微应用程序编排的核心。 AppsManager的主要目标是创建一个依赖关系树。 解决所有依赖性后,AppsManager将启动微应用程序。

装载机
客户端业务流程的另一个关键部分是Loader。 他负责为客户端下载应用程序。

路由器
为了执行客户端路由,我在microfe中实现了Router。 与传统的客户端路由器不同,microfe路由器功能有限。 它不处理页面,但处理微型应用程序。 假设我们有URL /content/detail/13和ContentMicroApp。 在这种情况下,microfe路由器将处理/content/*的URL并调用ContentMicroApp /detail/13

微孔
为了解决微型应用程序之间的客户端交互,我在microfe中实现了MicroAppStore。 它具有与Redux库类似的功能,但有一个警告:它在异步数据修改和reducer'a声明方面更加灵活。

***


服务器端可能实现起来稍微复杂一些,但结构更简单。 它由两个主要部分组成-StitchingServer和MicroAppServer。

微型应用服务器




可能的最小MicroAppServer功能可以表示为:init和服务。
启动MicroAppServer时,它应该做的第一件事是调用SticthingServer并向声明的微应用程序注册终结点。 它定义了MicroAppServer方案的依赖项,类型和URL,我认为谈论服务是不必要的-这里没有什么有趣的。

拼接服务器




StitchingServer允许您向MicroAppServers注册端点。 当MicroAppServer向StichingServer注册时,StichingServer记录MicroAppServer声明。

稍后,StitchingServer使用广告来从请求的URL解析MicroAppServices。

允许MicroAppServer及其所有依赖性之后,相应的公共URL将出现在CSS,JS和HTML中所有相应路径的名称中。 另一个步骤是向CSS选择器添加唯一的MicroAppServer前缀,以防止客户端上的微应用程序之间发生冲突。

然后StitchingServer的主要任务进入场景:所有接收到的部分的布局以及整个HTML页面的返回。

关于其他实现的几句话


甚至在2016年出现“微前端”一词之前,许多大公司就试图解决类似的问题,例如Facebook的BigPipe
现在,这个想法正在发展。 各种规模的公司都对此主题感兴趣,并为此投入了时间和金钱。 例如,Zalando提供了其Project Mosaic解决方案的开源代码。 我可以说microfe和Project Mosaic遵循相似的方法,但是存在一些基本的差异。 如果microfe求助于完全分散的路由以使每个微应用程序更加独立,则Project Mosaic将为每个路由选择集中式路由和模式定义。 顺便说一下,Project Mosaic可以轻松地即时进行AB测试和动态模板生成。

还有其他方法,特别是使用iframs作为连接层-显然,不是在服务器端,而是在客户端。 这是一个非常简单的解决方案,不需要特殊的服务器结构和DevOps的参与。 它可以由前端团队独立实施,这意味着它为公司减少了组织上的问题,并降低了成本。

仍然有一个单一的spa框架。 该项目依赖于每个应用程序的命名约定,以允许和下载微型应用程序。 容易掌握想法并遵循模式。 因此,该框架对于在您的本地环境中了解和试验系统很有用。 该项目的缺点是您必须以严格定义的方式构建每个微型应用程序-否则,框架可能不会接受它。

结论(和链接)


我认为,随着时间的流逝,关于微战线的话题将得到更详细的考虑。 如果它开始引起越来越多公司的关注,那么这个概念将成为大型团队的默认开发方法。 对于每个前端开发人员来说,在不久的将来熟悉此体系结构并获得使用它的宝贵经验将很有用。

micro fe应用程序注册服务器
微型前端基础架构

Source: https://habr.com/ru/post/zh-CN459540/


All Articles