带你快速了解微前端的拆分和集成

近年来,微服务大受欢迎。越来越多的组织开始使用这种类型的架构来避免大型单体的限制。

在本文中,我们将描述一种将“前端单体”分解为更小、更易于管理的部分的趋势。以及这种架构如何提高跨团队的效率。

图1

图 1 显示了一个应用程序,其中前端由一个“前端整体”组成,后端由多个微服务组成。

什么是微前端?

微前端的定义是:微前端的思想是将微服务的概念扩展到前端领域。

微前端的基本思想,是将你的前端拆分为一系列可独立部署且松散耦合的前端应用程序(称为微前端)。然后整合这些微前端以创建单个前端应用程序(参见图 2)。

如何拆分前端应用?

你可以在每页显示一个微前端,并使用超链接将其连接。也可以在一个页面上显示多个微前端(见图 2)。

图2

为了加快应用程序的开发,将微前端视为Web 应用程序的单个功能业务(单一职责)是可行的。每个“微前端”负责单个业务领域/用例,例如“配置文件”、“目录”、“订单”。它有自己的表现层、服务层(微服务)、持久层和独立的 数据库。从开发的角度来看,每个功能业务由一个团队实施。

为什么这会加快开发过程?每个团队都专注于一个业务领域,因此与其他团队的协调较少。这提高了开发的速度。

应用程序示例

下面我将描述一个使用微前端的示例应用程序。

想象一个网站,客户可以在其中订购外卖食品。

首先,你有一个登陆页面,客户可以在其中搜索餐厅(见图 4)。micro-frontend-browse-restaurants。

然后,每家餐厅都有自己的页面,在该页面上显示菜单项,客户可以选择他或她想要订购的东西(见图 3)。micro-frontend-order-food。

最后,客户有一个个人资料页面,他们可以在其中查看他们的订单历史记录、跟踪订单并自定义他们的付款选项。micro-frontend-user-profile。

本文的其余部分都使用此示例应用程序。

图3

应用程序的架构

此应用程序的架构如下:

每页显示几个微前端。并且有一个container 作为主要入口点(见图 4),主要负责:

  • 请求路由,并聚合来自后端的响应。
  • 管理横切关注点,例如身份验证、授权、日志记录、缓存和导航。
  • 聚合不同微前端在一个页面上,并确定哪个微前端什么时间应该被渲染在哪里。

图4

微前端的集成方法

“集成方法”的意思是:如何在前端“聚合”微前端?

图 5 显示了三种“集成方法”。

图5

构建时间集成

对于构建时集成,我们将每个单独的微前端作为一个包发布。在构建时,这些单独的微前端使用聚合的package.json。

Monorepo刻意用于构建时间集成 。使用 Monorepo,你可以管理多个存储库内的所有代码。库可以由特性、组件、实用程序或 UI 工具包组成。

Monorepo 的一大缺点是我们必须重新编译和发布 Monorepo 中的每个微前端,以在单独的微前端中发布更改!要维护 Monorepo,你可以使用Lerna、Nrwl 或 Angular Workplace。

服务器端集成

服务器端集成,是整合多个模板或片段在服务器上呈现 HTML 。这些片段代表微前端。

在下面的示例中,显示了一个index.html,它包含了其他 HTML 文件(参见图 7)。

图7

index.html

我们使用Nginx提供此文件(参见图 8),通过匹配请求的 URL 来配置 $PAGE 变量。

因此,如果用户选择 URL /browse,$PAGE 变量将填充 HTML browse 片段。

图8

运行时集成

运行时集成,指的是在运行时聚合和配置前端中的微前端(见图 5)。在这种情况下,package.json不再用于聚合各个微前端。

在下面的示例中,Web 组件用作创建单独微前端的技术。这些 Web 组件也可用于之前的“集成方法”。

什么是 Web 组件?

简而言之,Web Components 是你可以在 HTML 页面和 Web 应用程序中使用的独立组件。Web Components 也称为自定义元素。

作为开发人员,你可以编写自己的自定义元素,具有自己的 CSS、HTML 和 Javascript。此自定义元素基于 Web 标准,可用于最常用的浏览器。Web Components 是面向未来的,因为它们不依赖于框架或库。因此非常适合作为构建微前端的技术。

如何制作 Web 组件?

在此示例中,我们将通过示例应用程序的“订购食品”页面(参见图 3)自己创建一个 Web 组件。这个 Web 组件的名称是micro-frontend-order-food,在这个例子中(见图 9)有以下参数:data-name、data-img 和 data-menu。

图9

该 Web 组件的实现如下所示(参见图 10)。为了让这个例子简单,菜单项被省略了。

对于这个 Web 组件,我们首先定义一个扩展 HTMLElement的类。

使用HTMLElement,你可以创建自定义 HTML 元素。在构造函数中,首先调用 super(),这意味着 HTMLElement 的所有逻辑都可以用来构建 Web Component。接下来,我们将shadow DOM附加到 Web 组件。shadow DOM 是一个独立的 DOM(或“视图”),用于显示此 Web 组件的某些内容。

我们使用document.createElement(img)实例化所需的图像,并使用传递的参数设置 alt 和 src 属性:data-name和data-img。然后使用shadow.appendChild(img)将图像添加到我们的 shadow DOM 中。

图10

最后,定义了一个新的自定义元素/Web 组件:

customElements.define(‘ micro-frontend-order-food’, MicroFrontendOrderFood)

这个 Web 组件称为micro-frontend-order-food。我们可以在 HTML 页面中使用这些来显示带有文本的图像。

与 Web 组件的运行时集成示例

图 11 中显示了一个 index.html,它模拟了我们的示例应用程序(订购食物)。

这里的 index.html代表容器应用程序,它负责微前端的路由和渲染。在顶部,我们的微前端包含在<script> 标签中。刚刚讨论的micro-frontend-order-food定义在 JavaScript 包中:https://order.example.com/bundle.js

所述<div id="micro-frontend-root">是在所选择的微前端呈现占位符。常量webComponentsByRoute包含一个查找表,用于在你选择路由时确定要呈现的 Web 组件/微前端。

常量webComponentType包含基于所选路由的实际所选微前端,通过:window.location.pathname

图11

我们使用document.createElement (web ComponentType)实例化选定的微前端。最后,它链接到占位符:<div id="micro-frontend-root">。这是通过root.appendChild(webComponent) 完成的。

上面的示例虽然是一个简单示例,但它演示了 Runtime 集成方法。

使用哪种集成方法?

在下图(图 12)中,你可以推断出你可以在哪种情况下使用哪种集成方法。

对于小型和/或不复杂的应用程序(其中 1 或 2 个团队正在处理),你可以忽略集成方法而只假设前端单体。

图12

用户界面组件库

一个 UI 组件库由一系列 UI 构建块组成,例如输入元素、列表、标签栏和网格等。

你可以选择每个微前端都有自己的 UI 组件库(见图 13)。这样做的缺点是代码重复,并且 UI 组件的样式和操作的一致性可能会降低。

为了更加一致,我们还可以应用一个通用的UI 组件库。这样做的缺点是微前端然后通过这个库链接。如果你选择通用 UI 组件,请确保它仅包含UI 逻辑,不包含业务逻辑。

图13

微前端之间的通信

关于微前端最常见的问题之一是如何让它们相互通信。通常建议微前端尽可能少地进行通信,因为这会引入我们首先试图避免的不需要的链接。

也就是说,微前端之间通常需要一定量的通信。自定义事件允许微前端间接通信。可以使用“事件构造函数”创建事件,如下所示:New Event(build)(参见图 14)。

例如,dispatchEvent可以启动微前端X发布一个“构建”事件。然后微前端 Y监听此事件(使用addEventListener方法)并进行进一步处理。

图14

结论

微前端就是将大型 Web 应用程序分解为Verticals。这样以后,我们的技术选择、我们的代码库、我们的团队和我们的发布流程 (CI/CD) 理想情况下都可以彼此独立地工作,而无需过度与其他团队协作。这种架构也有一个缺点。这里我们提几点:

如果你想对整个 Web 应用程序进行更改,则需要对其他各个团队实施的各个微前端(和微服务)进行更改。

对于整个 Web 应用程序的集成测试,你必须启动许多不同的应用程序和服务器。难点在于测试微前端之间的依赖关系和通信。

独立构建的微前端可以包含重复的代码。重复的代码也意味着更多的维护、更多的出错机会以及 UI 组件的样式和操作的一致性降低。

此外,在许多实际案例中,微前端具有优势。随着时间的推移,Spotify 或宜家等大型组织已经成功地将微前端应用于旧代码的改造。借助微前端,这些公司可以更快地响应市场变化并提供推动其客户体验。

原文链接: https://dzone.com/articles/micro-frontends-by-example-8

上一篇:自动导出文件夹中所有的文件名列表 存为记事本格式


下一篇:IIS负载均衡-Application Request Route详解第四篇:使用ARR实现三层部署架构