微前端 101
什么是微前端(MFE)
优点是什么
缺点是什么
需要遵循的共同原则
我们如何实施 MFE
哟!
以前听过这个学期吗Micro Frontend
?或者MFE
觉得这到底是什么鬼?好吧,你来对地方了。在这门入门课上,Forte先生将概述以下内容:
- 什么是微前端(MFE)。
- 有什么优点。
- 有什么缺点?
- 要遵循的共同原则。
- 我们如何实现 MFE。
什么是微前端(MFE)
微前端只是一种架构设计方法,旨在将大型单体前端应用分解为多个可复用的小应用。我也喜欢称之为“拆开庞然大物”😈
这些较小的应用程序随后被托管在一个较大的应用程序内,我们称之为Host。
在主机和 MFE 之间,我们利用某种形式的 MFE 框架或适配器,它充当主机和 MFE 之间的粘合剂,允许主机安装/卸载 MFE 以及执行任何其他必要的工作,以使两者很好地协同工作。
每个 MFE 都将作为独立的、可独立部署的应用程序,与其他应用程序松散耦合。每个 MFE 还将拥有自己的 CI/CD 流水线,如下图所示。
优点是什么
1.可重用性
使用 MFE 的主要优势之一是,由于其松耦合的特性,它们能够在多个应用程序中复用。下图中,我有一个产品微前端,它的唯一职责是向客户端展示产品。它包含与产品相关的所有逻辑,除了提供与产品相关的功能外,不做任何其他事情。
2. 提高配送速度
微前端本质上是小型独立应用程序,拥有独立的持续集成和交付流水线。它允许独立的开发和发布周期,从而缩短构建时间。由于跨职能团队专注于微前端的开发,多个团队可以并行工作,最大限度地减少开发大型单体应用程序时可能遇到的障碍,从而提高交付速度。
3.可扩展性
随着组织的发展,越来越多的开发人员加入系统,您通常会发现他们面临的问题是如何随着组织的增长而扩展系统。
一个难点是入职时间,即:引导新开发人员并让他们快速熟悉整个系统所需的时间。如果是大型单体应用,这可能是一个真正的挑战。另一方面,我们可以让新开发人员开发 MFE,它只是整个系统的一小部分。这将使开发人员能够专注于系统的这一部分,从而更容易理解和快速上手,使他们能够更快地参与开发过程,然后逐步熟悉系统的其余部分。
由于微前端与系统其余部分松散耦合的性质,它允许一个团队的工作不影响另一个团队的工作,从而阻止团队互相干扰,从而提高上述开发速度,同时也有助于系统的持续增长。
4. 技术不可知论
MFE 的另一个主要优势是它允许团队选择最适合当前任务的技术栈。是否使用此功能取决于您自己,但微前端可以实现这一点。例如,我的主机应用程序可能用 Angular 编写,但我的 MFE 可能用 Vue 或 React 编写。
5. 脱钩
解耦的应用程序架构允许每个应用程序独立地执行其任务,完全自主,从而允许一个服务的更改不会影响另一个服务的更改。这种解耦的应用程序架构是微前端的主要优势之一,它也与可扩展性和系统增长能力息息相关。
6.维护
随着单体应用逐渐发展成为庞然大物,其规模和维护成本之间往往会存在关联。随着新功能的添加和现有代码的修改,可能会引入回归问题以及新的错误。
由于 MFE 是这些具有明确定义依赖关系的小型可管理应用程序,因此它使开发人员可以更轻松地构建应用程序的心理模型,从而使开发人员可以清楚地了解 MFE 的工作原理,从而使团队可以更轻松地维护和添加新功能。
7.容错
对于单体应用来说,如果系统的一部分发生故障,整个系统就无法正常工作。这也称为单点故障。而
对于 MFE,即使我们的微前端发生故障,也不会影响前端的其余部分。这使得系统更具弹性,更不容易发生故障。它还有助于创建更高可用性的系统,最大限度地减少停机时间,从而帮助我们进一步构建更可靠、更强大的系统。
缺点是什么
1. 复杂性增加
MFE 并非总是那么美好。作为工程师,我们做出的每一个架构决策都需要考虑其利弊。MFE 的主要缺点之一是设置 MFE 时会增加复杂性,因为两者之间必须存在某种中间地带,以便主机能够实现 MFE,而遥控器也能用作 MFE。
还有其他需要考虑的事情,例如路由以及我们的 MFE 如何与主机通信,反之亦然。这些事情在 MFE 中都会变得更加困难。
随着微前端数量的不断增长,整个系统的复杂性也将随之增加。我们的前端架构也有可能变成单体微服务,但只要精心规划并制定指导方针,就能有效降低这种风险。
2. 更大的有效载荷
在实现 MFE 时,可能会在 MFE 中出现一定程度的代码重复,并且根据您实现 MFE 的方式,这可能会导致在将应用程序呈现给客户端时产生更大的有效负载,从而导致性能下降,尽管有一些方法可以通过利用代码拆分等方法来有效地处理这个问题
3. 设计不一致
由于每个 MFE 都是独立的实体,因此当宿主渲染 MFE 时,设计可能会出现不一致。不过,我们可以通过在整个宿主和 MFE 中使用流行的组件库(例如Material UI)或创建 MFE 可以从父级继承的主题(例如:Tailwind 主题、Emotion 主题)来解决这个问题。
使用 MFE 的一个小问题是,根据您采取的方法,css 可能会发生冲突,因为一个 MFE 可能会带来与另一个 MFE 不同的样式,并且如果存在具有重叠样式的类、属性或 id,则一个 MFE 的样式可能会覆盖其他 MFE 的样式,从而导致我们的设计不一致。
以下是我们可以解决此问题的一些方法:
- 使用CSS-in-js库,例如Emotion
- 按照 (什么是 CSS 模块以及我们为什么需要它们)[ https://css-tricks.com/css-modules-part-1-need/ ]中的说明使用css-modules
4. 没有标准
在 MFE 领域中,没有既定的标准或最佳方法来实现微前端架构,因为实现 MFE 的方法有很多种,我们必须考虑实现适合我们特定用例的微前端的最佳方法,因为这在不同应用程序之间可能会有很大差异。
需要遵循的共同原则
领域驱动设计方法
领域驱动设计 (DDD) 是一种围绕业务领域对我们的软件进行建模的设计方法,通过将我们的系统分解为有界上下文,作为我们领域的边界。
例如,我们可能有一个应用程序,其中用户需要执行以下操作:
- 搜索产品。
- 完成一些订单流程以便捕获用户详细信息,即:地址、电子邮件、电话、姓名。
- 支付订单。
- 订单已发货。可能还会提供某种形式的包裹追踪服务。
这样,我们就可以将单体应用拆分成 4 个独立的 MFE。一个用于搜索产品,另一个用于订购、支付和配送。
之后,我们可以使用 BFF(Backend For Frontend,前端后端)作为 API 直接与各自的 MFE 打交道。每个 BFF 都包含直接处理自身领域功能的所有功能,例如:支付 BFF 包含验证信用卡、处理支付等所有逻辑。
如果我们愿意的话,这种方法将允许 4 个跨职能团队彼此并行工作并成为各自领域的大师。
不分享任何内容
每个 MFE 都应是一个独立的应用程序,与其他应用程序解耦。
一旦我们开始在 MFE 之间共享状态和逻辑等内容,就会跨越限界上下文,并在 MFE 内部形成一些重叠,这可能会导致我们走上单体微服务的黑暗之路。
因此,我建议,任何时候考虑在 MFE 之间共享某些内容时,都应该先退一步,认真思考一下 🤔
我们如何实施 MFE
在结束 MFE 101 课程之前,我想先讲一下 MFE 集成,以及一些你可能需要考虑的不同方案。
由于解决方案种类繁多,我只会介绍其中几种,但请记住,没有一种万能的方法可以适用于所有情况。在考虑如何实现 MFE 之前,我们必须权衡利弊,选择一种更适合我们用例的方法。
服务器端集成
采用这种方法,MFE 在服务器端合成后再发送到客户端。Facebook 也采用了类似的方法,尽管它将其 MFE 称为 Pagelet。它实现 MFE 的方式是在服务器上渲染模板,然后将其分发给客户端,同时 Web 服务器继续在后台生成 MFE,并将其提供给客户端,方法是用 Pagelet 的 HTML 标记替换相应的 div 占位符。如果您想了解更多关于 Facebook 的 MFE 实现方法,可以访问Facebook 工程。
构建时间集成
通过构建时集成,主机应用程序将在浏览器上呈现之前访问 MFE 的源代码。
这样做的好处是,将 MFE 设置为包非常容易,但缺点是,每次我们对 MFE 进行更改并重新部署时,都必须在主机中更改 MFE 包的包编号,然后重新部署主机。当我们将 MFE 设置为包时,还可能会开始混淆 MFE 和主机之间的界限,从而导致服务紧密耦合。
运行时集成
通过运行时集成,主机应用程序在浏览器中加载主机后即可访问 MFE 的源代码。采用运行时方法的优点在于,我们可以随时部署 MFE,并使其立即在主机中可见,或者我们可以对其进行版本控制,并让主机决定希望查看哪个版本的 MFE。缺点在于,工具和设置会更加复杂。
有很多方法可以在运行时将 MFE 集成到主机中,第一种是iframe。这种方法相对容易实现,并且有助于隔离主机应用程序和 MFE,使它们保持松散耦合。然而,使用 iframe 的缺点是,我们会失去所有可访问性,并且在构建响应式网站时会增加很多复杂性。
另一种方法是使用Webpack 模块联合,这是 Webpack 5 的新功能。
它允许开发人员创建多个独立的构建,然后在运行时与其他同样使用 Module Federation 插件的应用程序共享这些构建。Module Federation 的优点在于它使代码共享变得极其简单。虽然它并非专为微前端设计,但它非常适合集成 MFE,并且正逐渐成为 MFE 架构的主流方法。
在下图中,我们可以看到如何利用模块联合来创建 MFE 的构建。
当你的宿主应用程序加载时,它会获取 remoteEntry.js 文件,其中包含如何获取加载 MFE 所需的 JavaScript 文件的说明列表。Webpack 完成了大部分繁重的工作,主要只需要你作为开发者在 Webpack 配置中配置模块联合即可。
好吧,这就是我今天课程的全部内容,我希望大家喜欢这个关于微前端的简短介绍,并期待在下一节课中见到你们!
和平!
参考
- React 微前端:开发者完整指南
- 微前端课程 - 从初学者到专家
- 微前端 - Martin Fowler
- 微前端将微服务理念延伸到前端开发
- Webpack 模块联合
- 微前端架构 - Luca Mezzalira,DAZN
- 微前端:是什么、为什么以及如何