从单体到微前端:REA移动应用开发的革新之路

发表时间: 2023-04-10 09:19

21 月 3 日,REA Group 举办了第二次 Unstack'd 活动,作为我们向外部开发社区分享我们的技术的举措的一部分。这一次,主题是关于移动相关的话题。

在这里,我将共享项目转录到博客中,以便于阅读。您也可以 从此处获取录音。

REA 的移动时间轴。

REA 于 1995 年开始主要通过网络提供我们的内容。

随着 Apple iOS 的兴起,我们在 2010 年推出了 iOS Residential App,并在 2012 年推出了 iOS RealCommercial App。

谷歌随后出现并推出了 Android,这是另一个也很受欢迎的智能手机平台。2014年推出Android Residential App,2016年推出Android RealCommercial App。

接下来,移动平台继续增长。然后,我们在市场上推出了另外 2 个应用程序,即适用于 iOS 和 Android 平台的 Ignite 应用程序和 Flatmate 应用程序。

住宅应用程序时间表

在本次演讲中,重点是我们的主要住宅应用程序。

我们在 2010 年成立了一个 iOS 团队来进行 iOS 开发。然后我们在 2014 年为我们的 Android 开发建立了一个不同的团队。

快进到今天,我们有大约 10 个不同的团队,包括 iOS 和 Android,他们为住宅应用程序开发做出了贡献。

本次演讲的重点是,我们如何发展我们的架构以实现从 2014 年到今天的扩展。

目标和指南。

在我们朝着更好的架构迈进的过程中,我们必须实现一些我们想要实现的目标,以及一些构成我们发展基础的指南。

我们希望在高层实现的 3 个目标是

  • 开发可扩展性——我们希望确保当我们需要更多功能时,我们可以轻松地可扩展地添加它们
  • 开发灵活性——我们希望团队在技术和设计发展方面具有灵活性和自主权,而不会互相踩到脚趾。
  • 开发人员体验——我们希望我们的开发人员拥有丰富的开发经验,并乐于为代码库做出贡献。

同时对我们的移动开发有一些基本的指导

  • 我们希望在我们的移动开发中尽可能接近该平台,因为从长远来看它更可靠。因此我们的开发是使用Android和iOS原生开发平台。
  • 我们希望在我们的移动开发中使用最新的行业趋势技术堆栈,以确保我们不会过时。我们希望所有新功能都使用 Swift 和 SwiftUI 进行 iOS 开发;使用 Kotlin 和 Jetpack Compose 进行 Android 开发。

三个时代

为了提供和说明我们是如何走到今天这一步的,最好看看我们是如何走过移动开发的不同时代的。

我们将开发阶段分为 3 个时代。在本节中,我将讨论这两个时代,然后再进入本次演讲的主题,即微前端时代。

巨石时代

众所周知,我们早在 2010 年就开始了 iOS 团队。我们学到了很多关于 iOS 开发的知识。我们跟随平台的快速变化,我们在同一个代码库中学习、成长和发展,代码库中有各种 iOS 开发技术堆栈的片段。

然后在 2014 年,我们成立了一个不同的团队,Android 团队。同样,我们在同一个代码库中学习、成长和发展。

在某些时候,我们还聘请了一些外部承包商来为项目做出贡献。他们来这里也是为了提高团队的技能并进一步发展我们的代码库。承包商在我们这里完成了他们的任期,留下我们自己的 Android 和 iOS 团队继续进行这些项目。

在此期间,很高兴我们成功交付了数百万的应用程序。尽管如此,我们的结构确实存在一些明显的问题。

  • iOS 和 Android 团队截然不同,具有不同的体系结构和代码结构
  • 由于技术的快速变化和发展,随着人员流动,我们的代码结构变得混乱。
  • 手机行业持续增长。单一的移动开发团队是交付的瓶颈
  • 移动设备仍然是网络通用服务的副产品。因此,移动开发通常必须具有适应性。

面对这些挑战,我们将我们的开发发展为我们所说的联合开发。

联邦时代。

联邦时代是为了解决我们在巨石时代遇到的问题

首先,我们将 iOS 和 Android 团队合并,组成一个架构团队。这很棒,因为我们可以使跨两个平台的结构更加一致。

该架构团队还负责一项新的移动优先服务,通常称为前端移动后端 (BFF)。这个 Mobile BFF 保护移动开发免受服务变化的影响,并为移动提供它需要的一流公民服务。

我们还组建了一个功能团队,负责所有面向用户的功能开发。这也是iOS-Android联合团队结构。

为了扩大我们的开发规模,我们允许其他企业的团队为我们的代码库做出贡献。他们构建联合模块。随着时间的推移,除了模块之外,他们还为该功能做出了贡献。

联邦时代如何提供帮助。

有了这个,我们就解决了 Monolith 时代的所有问题。

  • 我们现在将 iOS 和 Android 团队合并在一起,以确保代码更加一致
  • 我们有更好的模块化代码结构划分架构层和功能层
  • 我们扩展我们的开发,允许其他团队联合到我们的代码库中
  • 我们现在有一个专门的移动 BFF,可以保护我们的移动开发免受服务变化的影响

尽管如此,从上面的结构中,我们还是可以发现一些问题。

挑战联邦时代。

  • 由于我们仍然拥有用于架构和联合的单一代码库,因此架构和功能团队的监管权变得不明确。
  • 虽然我们有一些结构,但边界仍然相对模糊。什么叫特征,什么叫子特征?
  • 为了对代码库做出贡献,联邦团队需要遵守限制模式。他们来来去去,从来没有主人翁意识
  • Mobile BFF 不是为联合而设计的。它现在挤满了来自许多团队的贡献。

看到这些挑战,我们进一步探索如何改进。

这就是我们如何发展到微前端时代。

微前端时代。

微前端的想法来自于微服务。

虽然它看起来像模块化开发,但它是不同的。关键字是 可独立开发的前端应用程序

这就像我们可以一起建造小房子并将它们组合在一起以实现协作功能,而不是建造一座大房子。

应用程序作为平台。

另一种看待它的方式,就像将我们的应用程序作为一个平台。

举个例子,我们有一个 Android 设备。如果他们使用提供的 Android SDK,任何人都可以构建应用程序并将其放入设备

同样,我们将我们的应用程序视为一个平台。它就像一个顶层,我们称之为 App Shell Layer。

如果任何企业想在应用程序中添加功能,他们需要使用我们提供的基础库来构建他们的功能。我们将其命名为基础层

业务团队可以构建小应用程序,这些应用程序可以捆绑到 App Shell 中,并作为一个应用程序交付给我们的最终用户。这些小应用程序,我们称它们为微前端,或简称为 (MFE)。该层也称为 MFE 层。这个小应用程序可以单独分发到我们的应用程序库中,并单独进行测试。

应用外壳层

进一步说明这种架构是如何工作的。让我们深入到第一层,App Shell 层

它有几个职责

  • 在那里配置应用程序的所有初始需求
  • 它是应用程序的入口,它在其中启动应用程序、恢复状态并处理任何深层链接
  • 最后也是最重要的一块,App 有 AppFrame 和 Routing。该层负责托管 MFE 并将其显示给用户

为了更好地说明 AppFrame 和 Routing 是什么,请参考上图的右侧。AppFrame 就像可以放置 MFE 的隔间。

然后我们有一个 MFE 列表,它们可以通过我们拥有的路由机制放置在 AppFrame 中的相应隔间中。我们还将深度链接链接到我们的路由机制,以便它们都作为一个统一的实体工作。

从这里我们可能会认为每个 MFE 都是一个屏幕层。但实际上并非如此。它包含的不仅仅是一个屏幕层。

为了更好地理解这一点,让我们进一步放大每个 MFE 的外观,如下图所示。

这里有几个 MFE,每个 MFE 都不仅仅是一个屏幕本身。这是一个用户体验

  • 他们可以满足彼此相邻的多个屏幕,就像我们在 Ipad 上一样
  • 或者当它们处于 iPhone 模式时,它们可以是单个屏幕,可以点击更深入的细节,可以出来。
  • 或者它们可以像向导样式一样,从一个屏幕链接到另一个屏幕
  • 有时,他们可以公开多个屏幕以从 AppFrame 进行路由

从这里,您可以看到,它们中的每一个都是用户体验本身,而不是单个屏幕。

MFE 层。

现在,让我们进入 MFE 层。

这些 MFE 中的每一个都由负责该功能的业务部门完全拥有。它们都可以编译为单独的应用程序,并发送到 REA 应用程序库以进行测试

准备就绪后,它们将全部捆绑在一起并编译到我们的主应用程序中。然后可以将主应用程序发送到 REA 应用程序库进行测试,以及 PlayStore 和 AppStore 供外部使用。

对齐自治。

从这里,您可以清楚地看到 每个团队的自主权

  • 我们有明确的分离和所有权
  • 每个团队都有技术结构的灵活性,它的设计
  • 它们的代码库更小,更易于使用,并且
  • 每个都可以单独作为应用程序交付

同时,它们应该很好地 对齐,在哪里

  • 他们必须使用 REA Foundation
  • 它们使用路由链接到其他 MFE,并且可包含在 AppFrame 中
  • 没有MFE应该相互依赖

我们看两者,这就是通常所说的 ALIGNED AUTONOMY。

没有 MFE 依赖项。

MFE 开发的要求之一是,不应存在 MFE 依赖项。对于 2 MFE 进行通信或具有相关功能,它们必须要么

  • 使用路由
  • 使用 REA 基金会
  • 甚至有时会跨 MFE 复制功能

我们希望尽可能避免在少数 MFE 中必须通用的东西。然而,有时我们无法避免只在 2 个 MFE 之间需要一些共同点,我们如何解决这个问题?

MFE 组件共享。

我们通过 MFE 组件共享来做到这一点

如果我们要查看我们的微前端架构,我们在顶部有 App Shell 层,在底部有基础层。在这两者之间,我们有我们的 MFE 层,每个 MFE 由各自的团队拥有。

在大多数情况下,MFE 与其他 MFE 没有任何共同点,因此不需要这样的组成部分。(根据上图,MFE 3)

然而,为了让 MFE 共享一些共同点,我们引入了组件层。该组件可由各自的 MFE 所有者共享,并可由其他 MFE 访问。

也有一些团队不需要任何全屏功能,但想利用其他 MFE 的屏幕来显示他们的部分,他们可以只让团队工作的组件部分在其他 MFE 屏幕上显示。(这在上面的 Comp 3 中有说明)

这两层(MFE Screen 和 MFE Component)构成了我们的 MFE 层。

基础层。

最后,基础层,它是我们 MFE 的基本开发包。

这是提供 MFE 所需的共同需求的层。

  • 基金会不应仅仅满足任何特定的 MFE 需求。
  • 通过提供合理的默认值,它们有助于确保 MFE 之间的一致性和一致性。
  • 它们也是可定制的,可以扩展以供多个应用程序使用。

在 REA,我们有两个不同的基础构成了这个基础层

  • 能力——这提供了非 UI 特定于 MFE 的通用功能,例如网络、分析、身份验证等。
  • 设计套件——提供与 UI 相关的功能,以确保跨 MFE 的设计一致性,例如颜色、排版、辅助功能等。

Foundation和MFE的可扩展性。

为基金会创建的长期计划并不意味着只在 REA 内使用一个应用程序。我们希望它可以扩展到 App 之外。

与 MFE 类似,它们也可以扩展到一个应用之外。但这只有在我们设计适合它的基础时才有可能,如下所述。

不可扩展设计

假设我们有一个使用 MFE 1 的 X 应用程序,它需要 Firebase Experiment

面向对象设计的角度来看,我们从基础开始实施 Firebase Experiment,并将 MFE 1 链接到它。对于 Y 应用程序,如果需要 Optimizely Experiments,那么我们有 MFE 1 链接到 Optimizely Experiments。

虽然从基本的 OOP 设计来看这似乎是合理的,但 MFE 不能扩展到应用程序之外。原因是因为现在 MFE 1 与基础的链接必须绑定到 Firebase 或 Optimizely。MFE 需要修改才能被其他应用程序使用。

可扩展设计

为了避免这个问题,我们需要以相反的方式设计我们的基础

在这里,我们将 MFE 直接链接到基础,而不是具体的。

具体的,我们让我们的X App和Y App配置自己特定的基础需求。

这将确保 MFE 不绑定到任何特定的基础层,并使 MFE 和基础层都可以扩展到一个应用程序之外。

我们怎么样?

如果我们要整体审视我们的 MFE 架构,并反映我们最初的 3 个目标。我们已经实现了所有这些目标!

  • 我们可以看到,有了 MFE,现在它是可扩展的。我们只需要轻松地将新的 MFE 作为新的用户体验添加到应用程序中
  • 它们彼此独立,并且在设计和工作方式上具有灵活性
  • 开发人员也很乐意在 MFE 上工作,因为他们不需要担心整个代码库,只需专注于他们最感兴趣的用户体验。他们可以自由探索引入的新技术。

进两步退一步

俗话说,进两步退一步。一路上我们确实遇到了一些痛苦。

如果我们看下表

微前端更好

  • 它在清晰的代码所有权方面显然胜出
  • 团队敏捷性和自主性在微前端中也比单体更好
  • 每个功能都可以在微前端中更快地构建

尽管如此,我们确实倒退了,Monolith 更适合

  • 更容易整合
  • 依赖同步和
  • 共同基础设施升级

了解这些痛苦后,我们现在正在研究是否有办法在所有方框上打勾。

还没有走出困境……但我们看到了光明

显然,我们还没有走出困境,前面还有一些挑战。

还有一些遗留的单体功能我们还没有迁移到微前端架构,我们需要继续努力。

但我们确实看到了光芒。

我们有一个解决方案,它确实可以帮助我们比过去更好地扩展我们的移动开发,开发人员期待着在过去的工作。

学分

在结束之前,让我把功劳分享给以下人

感谢 Unstack'd 团队的大部分设置、审查和许多计划,使这次活动成为可能

还要感谢开创性的架构师和技术主管,他们在 REA 中率先推出了最初的微前端架构。

也非常感谢整个 REA 移动团队,他们不懈地使 REA 的这种架构成为可能。

作者:Elisha Lye

出处
:https://www.rea-group.com/about-us/news-and-insights/blog/from-monolith-to-micro-frontends-how-we-revolutionised-rea-mobile-app-development/