带你快速了解微前端的拆分和集成
目录什么是微前端?如何拆分前端应用?应用程序示例应用程序的架构微前端的集成方法构建时间集成服务器端集成index.html运行时集成什么是 Web 组件?如何制作 Web 组件?与 Web 组件的运行时集成示例使用哪种集成方法?用户界面组件库微前端之间的通信结论近年来,微服务大受欢迎。越来越多的组织开始使用这种类型的架构来避免大型单体的限制。在本文中,我们将描述一种将“前端单体”分解为更小、更易于
目录
近年来,微服务大受欢迎。越来越多的组织开始使用这种类型的架构来避免大型单体的限制。
在本文中,我们将描述一种将“前端单体”分解为更小、更易于管理的部分的趋势。以及这种架构如何提高跨团队的效率。
图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 或宜家等大型组织已经成功地将微前端应用于旧代码的改造。借助微前端,这些公司可以更快地响应市场变化并提供推动其客户体验。
更多推荐
所有评论(0)