探索微前端的未来发展

发表时间: 2022-05-17 17:09

本文最初发布于博客 Better Programming。


从 2021 年年底到 2022 年最初的几周里,我花了一些时间来研究微前端到目前为止的发展情况。


我分析了让团队陷入挣扎的不同挑战,长期以来导致耦合的反模式,以及用于解决这些问题常用的模式。


我们发现,微前端使团队能够独立工作,为中大型应用程序做出贡献,迭代演进我们的应用程序,减少潜在问题的影响范围。


然而,分析不能停留在我们到目前为止所取得的成就上。我们要向前看,向未来迈进。


我必须了解下,这个迷人的拼图中缺少了哪一部分,并设想下,怎么做才会使这个架构方法变得更好。

在这篇文章中,我将分享一些想法和趋势,它们可能会在微前端社区引发一些有趣的讨论。


本文所涉及的话题考虑了这种架构的客户端、服务端和边缘端实现。


最后,我会分享下 2022 年我将关注微前端生态系统的哪些方面。

增加事先设计


微前端架构的主要挑战之一是回答这样一个问题:微前端有多 "微"?


许多组织都面临这个问题。在现实中,答案不只一个,我们需要了解背景、组织结构及其规模,以及团队之间的沟通渠道。


在与数个从事分布式架构工作的团队的几次接触中,我发现,“分布式组件”的实现比微前端多得多。通过分布式组件,领域知识在容器和“微前端”之间,甚至是容器和多个“微前端”之间共享。


我们仍在努力寻找正确的边界,有时,我们在实施微前端时却不知道如何解释微前端。我认为,理解微前端是迈向更高成熟度的必要步骤,掌握应用业务子域并不是一件容易的事,需要我们对正在构建的应用有深入的了解。


不过,我认为有一个可能的解决方案可以缓解这一挑战。


前期借助白板花更多的时间进行讨论,在不影响用户体验的情况下,和组织的多个部分一起修改业务领域划分。这是必须的。


当我们从这些会议中走出来的时候,应该有足够的信心来启动这个项目,并定期审查我们的决定,以确保最初的假设对于目标的实现仍然有效。


请记住,我们不可能在前期考虑到所有方面,现在的企业和组织很可能在 6 或 12 个月后发生变化,所以我们应该定期地重新审视我们划定的微前端边界。


另外,永远不要忘记组织结构和软件架构之间的联系,意识到这一点并在设计决策中考虑这一点非常重要。

微前端通信


当同一个视图中有多个微前端时,它们有时候需要相互通信。在我为设计微前端而创建的心理模型中,我建议微前端之间使用发布-订阅模式进行通信,严格执行微前端之间的边界,避免或至少减少设计时耦合,让团队有更大的自主性。


在技术上,实现这种模式有几种选择,如自定义事件、事件发射器库甚或反应流。


在过去的几个月里,出现了一个重要需求,我一开始并没怎么强调,可能是因为我把它当成了理所当然,但现在看,这绝对是需要注意的事情。


就像后端的事件驱动架构一样,一个清晰的事件模式有助于避免在集成阶段犯错。此外,模式还能帮助那些不直接从事代码库工作的技术人员,清楚地了解特定应用程序内部发生了什么。


我在我关注的众多 Slack 频道中发现了这个事件总线库,毫无疑问,它非常有助于在松耦合的元素(微前端,但不限于此)之间实现更结构化的通信:
https://www.npmjs.com/package/@trutoo/event-bus。


用于微前端通信的 @trutoo/event-bus


考虑到微前端是一个分布式架构,需要有一个更规范的 API 或事件管理。API 或事件也是团队交互的方式,而不仅仅是微前端交互的方式。


我们必须明白,这些做法不仅可以帮助开发者在发送事件时避免错误,还可以促进团队之间的讨论,明确意图。


我希望,将来,当我们有大量使用松耦合通信策略的大型应用时,会投入更多的精力来简化开发体验。

如果每次我们新开发微前端之间的交互时,都有一个事件注册表可以查询,那该有多好?


最后,如果你没看过 PayPal 在微前端通信方面所做的工作,我强烈建议你观看这段精彩的视频。

服务端渲染(SSR)


在过去几个月中,服务端渲染架构是创新比较多的领域,想想 Next.js 或者 React 18 背后的团队对服务器组件的投入。


微前端也有一些有趣的解决方案,比如Next.js模块联盟、Piral、TailorX、ILC等等。


对于 SSR 微前端应用,有不少我们应该开始进行更深入研究的话题。


以下是我认为到目前为止这个领域中存在的一些空白:


  • 微前端发现就像微服务的服务发现模式,但应用于前端。使用这种模式,我们可以动态组合微前端,而不需要对系统中的端点进行任何静态引用。想象一下,一个微前端基础设施会自动把自己注册到一个发现服务中,而 UI 设计器会从发现服务中检索微前端,而不是直接与微前端进行点对点的联系。
  • 云端参考架构:在如何使用流行的云供应商构建 SSR 微前端架构方面缺乏指导。这是一个相对来说可以快速解决的问题,我愿意尽可能地提供帮助。
  • 在微前端中利用无服务器范式:我相信,无服务器可以提供很好的开发速度,将基础设施的管理委托给云供应商。同时,我们必须转变思路,了解特定的工作负载(如微前端)应该利用哪些服务。例如,我认为,使用 AWS Step Functions 这样的服务来简化微前端的创建是有价值的,因为它很好地实现了与整个 AWS 生态系统的集成。这使我们能够采用低代码模式,从长远来看,可以简化维护工作。这是我们可以在云上使用的许多模式中的一种,但用微前端探索这些模式非常引人入胜(至少对我来说是如此)。
  • 一种框架无关的 React 服务器组件方法:当后端数据发生变化时,有一种机制可以使用 SSR 原子化地重新加载视图的一部分,并与客户端的微前端无缝集成。这样可以提供混合了 CSR 和 SSR 的混合架构,针对每个微前端使用正确的方法。也许我们今天就可以创建这样的机制,但像 React 18 那样有一个优美的实现将是最终的目标。


如你所见,有很多机会摆在我们面前,有些比较具体,比如参考架构,有些是比较长期的,比如框架无关的 React 服务器组件方法。


在这个列表中,我将重点关注参考架构以及研究在微前端使用无服务器范式。我已经开始研究参考架构的原型,在无服务器方面我也有一些有趣的原型。敬请关注。

部分水合(Partial hydration)


性能对每个前端应用程序来说都很关键,包括微前端。


我已经有一段时间没有听说过“岛屿架构”的概念了。不过我认为,最终,鉴于其原则和特点,这种架构可能属于微前端范畴。


岛屿架构所引入了有趣的技术,有可能利用局部水合来提高服务器端渲染应用程序的性能。


简而言之,不是对整个页面进行水合,而只是立即对用户可见的“岛屿”进行水合,其他部分将在用户看到时进行水合。


部分水合并不是一项新技术,从 2019 年开始就有了(如果我没记错的话),但我没有看到任何微前端应用涉及这项技术。考虑到微前端的性质和部分水合的机制,我认为这种技术应该获得更多的青睐,从而进一步优化我们的 SSR 微前端应用。


在这条推文中,Addy Osmani 提供了一些有用的资源,可以帮助你更好地理解这个概念。


最后,如果你对这个话题感兴趣,那么建议你阅读下这篇文章,其中有一个 UI 框架清单,它们可能使用了部分水合。


目前,我正使用 Preact 进行一个微前端概念验证实验,希望能把我的收获尽快和大家分享。

微前端和边缘计算


在讨论边缘的微前端时,我们经常会想到Edge-Side Includes(ESI)标记语言。我这里指的是许多 CDN 正在提供的计算能力,如边缘的 AWS Lambda 或 Cloudflare workers。


边缘技术正在快速发展,因此部分应用可以移到边缘,改善解决方案的延迟和可扩展性。不过,在许多 Web 应用中,我们不能只考虑使用多个微前端生成一个 HTML 页面的计算工作量,还需要考虑整个应用的复杂性。


通常,计算是如今“最容易”解决的问题,当涉及到数据重力(数据库、多区域数据复制、全球性基础设施的写与读、数据复制延迟......)或身份验证时(通常集中在云基础设施的一个特定区域甚或内部的一个数据中心,而且安全性很高)就不那么容易了。


的确,SSR 微前端应用可以从边缘计算中获益,但它们需要访问众多其他资源(数据、身份验证、缓存......),而这些资源在边缘并非完全可用。


除非我们有一个封装得非常好的工作负载,不需要其中的任何外部依赖,否则我们还无法真正把边缘的能力全部利用起来。


我相信,未来我们会更多地采用边缘技术,但同时,我认为我们必须更好地理解边缘技术在哪些方面可以对我们的工作负载产生真正的影响,而不仅仅是因为使用边缘节点看起来“很酷”(炒作驱动开发)。


在我看来,在不久的将来,边缘计算将与微前端产生密切的联系,特别是对于提高应用程序的性能来说,但它并不像现在看起来那么简单。

部署


在微服务中,有一套统一的做法来降低微服务新版本的部署风险,如特性标识、蓝绿部署和金丝雀发布。


在过去的 12 个月中,我在微前端领域没有看到类似的工作,特性标识除外,这看起来是许多团队都熟知的一个模式。


我认为,必须有一种部署策略可以让开发团队建立信心。


分布式系统中,持续部署通常是常态,我们必须为开发人员提供安全保障,使他们能够通过迭代的方式,快速将代码从笔记本电脑发布到生产环境中,而降低一次性部署让所有用户都受 Bug 影响的风险。


对于 SSR 微前端,我们很容易重用现有的工具和实践,利用这些机制的一种来发布我们的基础设施,尽管这些策略通常不被客户端渲染的微前端应用程序所接受。


我们可以通过多种方式实现它们:客户端、服务端甚至是边缘端。


我的建议是尽快实施这些策略中的一种,因为它们可以为你的团队创造一个更安全的环境,结果可能会让你惊讶……积极的方面。

路由


和部署策略密切相关,客户端渲染的微前端应用程序缺乏可靠的路由策略。所有实现都使用了我们用于实现单体架构的路由库。与此相反,我认为我们可以做得更好!


当我们将路由库与前面介绍的部署策略混在一起时,就可以有一个非常智能的路由,它可以照顾到较新的微前端版本、不同的环境,甚至不同的用户角色。


我们也可以有一些工具,逐渐增加某个版本的流量,并且可以用同样的方式执行回滚。


例如,当我们在 AWS 中开发容器或无服务器工作负载时,可以通过几行配置轻松创建我们喜欢的部署策略。


使用AWS SAM实现一个AWS Lambda Function的金丝雀发布


应用程序前端的路由可以通过提供了不同可能性的外部 JSON 轻松编排,而不需要将这些信息集成到应用程序逻辑中。


最后,当这个静态 JSON 与部署逻辑相结合时,我相信它们可以带来很多价值,降低新版本的风险,并允许基于业务想要实现的任何逻辑进行动态配置。


路由和部署绝对是我最感兴趣的领域。在接下来的几个月里,我将花些时间来消除那些无差别的繁琐工作,让团队更好地控制他们的部署和路由。我希望可以尽快分享我正在做的工作,因为工作组对这两个主题非常感兴趣。

微前端管理


这个领域我还没有研究,但是我有一个工具列表,可以用来理解微前端的利弊。我主要关注的是单库,因为我认为,如果使用库,就不需要额外的工具来管理代码,就像在同一个库中有多个独立的项目那样。


目前,以下工具引起了我的注意:


  • Turborepo
  • PNPM
  • Projen


我相信,它们都有一些特性,可以帮助我们构建一个单库策略,改善开发体验。


这是我今年的一个延伸目标,我不确定自己是否能够投入足够的时间来考察每个工具,但我肯定会关注这个领域,因为我相信还有更多未探索的领域可以进一步改善开发体验。


任何关于工具的建议都非常受欢迎,如果可以在分享经验时提供简单的评论就更好了。

小结


如你所见,在微前端生态系统中仍然有很多领域需要探索,我们在过去几年里已经取得了很大的进步。

对我来说,这是一个非常令人兴奋的机会,可以影响一个正在全球企业组织中提高成功率的“年轻”架构多方面的改进。


我相信,还有更多的东西需要去探索和发现,我希望这种快速的采用可以帮助我们了解,什么在分布式 UI 架构中可行,什么不可行。


我的雷达上还有其他主题,如 WebAssembly、增强客户端安全性、进一步简化开发体验等等,但这篇文章中列出的主题应该已经可以为所有社区提供思考的素材,以便在未来几个月内改进这种新的方式,进而扩展我们的应用程序和组织。