写点什么

对微前端的 11 个错误认识

2020 年 10 月 11 日

对微前端的11个错误认识

本文最初发布于 Bits and Pieces 博客,经原作者授权由 InfoQ 中文站翻译并分享。


微前端是一个可以追溯到多年前的新趋势。随着新方法的出现以及各种挑战被克服,它们正在慢慢地进入主流。但遗憾的是,许多非常明显的认识误区,让许多人很难理解微前端到底是什么。


简而言之,微前端就是将微服务的一些好处引入前端。除此之外,我们不应该忘记,微服务也不是什么“银弹”。


提示:要在微前端或任何其他项目之间共享 React/Angular/Vue 组件,可以使用像Bit这样的工具。它允许你从任何代码库中“harvest”组件,并将它们共享到bit.dev的一个集合中。它让团队可以在任何存储库中使用你的组件。使用它可以优化协作、加速开发和保持 UI 一致性。



示例:在 bit.dev 中查找共享 React 组件


认识误区


我想列一下在过去几个月中,我最常听到的关于微前端的误解。先从从一个明显的例子开始。


微前端需要 JavaScript


目前,许多微前端解决方案都是 JavaScript 框架。这怎么可能错呢?JavaScript 不再是可选的。每个人都想要高度交互的体验,而 JS 在提供这些体验中发挥着至关重要的作用。


除了加载速度快、可访问 Web 应用的优点外,还有其他因素应该考虑。因此,许多 JavaScript 框架都提供了 isomorphic 渲染能力。最终,这让它们不仅能够在客户端进行拼接(stitch),还能在服务器上准备好一切。如果有性能要求(如第一次有意义渲染的初始时间),这个选项听起来很不错。


请记住,isomorphic渲染有其自身的挑战。


然而,即使一个 JavaScript 解决方案没有提供 isomorphic 呈现,这也没什么问题。如果不想在构建微前端时使用 JavaScript,我们当然可以这样做。有许多模式,其中很多根本不需要 JavaScript。


考虑一种“比较旧的”模式:使用<frameset>。我听见你笑了?好吧,有一些现如今人们试图做的分割,它以前就支持了(下文有更详细的讨论)。一个页面(可能由另一个服务渲染)负责菜单,而另一个页面负责标题。


<frameset cols="25%,*,25%">  <frame src="menu.html">  <frame src="content.html">  <frame src="sidebar.html"></frameset>
复制代码


如今,我们使用更灵活(且仍然受到活跃支持)的<iframe>元素。它们提供了一些很好的特性——最重要的是使得不同的微前端相互隔离,但仍然可以通过postMessage进行通信。


微前端只在客户端有效


在 JavaScript 认识误区之后,这是下一个层次。当然,在客户端有多种技术可以实现微前端,实际上,我们甚至不需要<iframe>或任何类似的技术。


微前端可以像服务器端“includes”一样简单。有了诸如 Edge Side Includes 之类的高级技术,这将变得更加强大。如果我们排除了在微前端功能中实现的微前端场景,那么即使是简单的链接也可以很好的工作。最终,微前端解决方案也能像小而独立的服务器端渲染器一样简单。每个渲染器可能只有一个页面那么小。


下图展示了在反向代理中发生的更高级的拼接:



通过反向代理实现服务器端拼接


当然,可能 JavaScript 有许多优点,但它仍然高度依赖于你试图通过微前端解决的问题。根据你的需要,服务器端解决方案可能仍然是最好的(或者至少是更好的)选择。


你应该使用多个框架


在几乎每一个关于微前端的教程中,不同的部分不仅由不同的团队开发,而且使用了不同的技术。这是假的。


适当的微前端方法可能使用不同的技术,但是,这不应该是目标。我们做微服务也不只是为了在后端拼凑技术。如果我们使用多种技术,那只是因为我们获得了一个特定的好处。


我们的目标应该始终是某种统一性。最好的方法是考虑一个新项目:我们会怎么做?如果答案是“使用单一框架”,那么我们就走上正轨了。


长远来看,有很多原因可以解释为什么应用程序中会出现多个框架。可能是遗留的,可能为了方便,也可能是一个概念验证。无论是什么原因:能够处理这种场景还是不错的,但它绝不应该是开始就希望达到的状态。


不管你的微前端框架多高效——使用多个框架总是要付出不可忽视的代价。不仅初始渲染会花费更长的时间,而且内存消耗也会朝着错误的方向发展。不能使用方便模型(例如,针对某个框架的模式库)。需要更多的重复。最终,程序的 Bug 数量、不一致行为和可感知的响应性都会受到影响。


按技术组件划分


一般来说,这没有多大意义。我还没见过微服务后端的数据处理在一个服务中而 API 在另一个服务中。通常,服务由多个层组成。虽然某些技术内容(如日志记录)肯定会引入到公共服务中,但有时也会使用诸如 Sidecar 之类的技术。此外,还需要通用服务编程技术。


对于微前端,情况也是如此。为什么一个微前端只能做菜单?每个微前端都有相应的菜单吗?拆分应该根据业务需求来做,而不是技术决策。如果你读过一些关于领域驱动设计的书,你就会知道它是关于定义这些领域的——而这个定义与任何技术要求无关。


考虑以下划分:



按布局分解成微前端


这些都是技术组件,和微前端无关。在一个真实的微前端应用程序中,屏幕可能看起来是这样的。



按领域分解成微前端


的确,这里的拼接要复杂得多,但这是一个可靠的微前端应用程序应该为你提供的!


不应该共享任何东西


不。你应该共享那些值得共享的东西。你绝对不应该共享所有东西(见下一条)。但要做到始终如一,你至少需要共享一套原则。至于是通过共享库、共享 URL,或者只是在构建或设计应用程序时使用的文档,那就不重要了。


对于微服务,“无共享”架构如下图所示:



微服务的“无共享”架构


在浏览器中,这将导致使用<iframe>,因为目前没有其他方法可以防止资源泄漏。使用影子 DOM,则 CSS 可能会被隔离,但脚本层面仍然能访问所有内容。


即使想遵循无共享的架构,我们也会遇到麻烦。


当然,共享的程度越深(例如,使用一个通过应用 shell 追加到 DOM 的共享库),就越会出问题。另一方面,共享程度越浅(例如,只是一个指定基本设计元素的文档),就会出现更多的不一致性。


应该共享一切


绝对不是。如果这样想,那么单体更有意义。就性能而言,这可能已经是一个问题了。什么可以延迟加载?我们能去掉一些东西吗?但真正的问题是依赖管理。什么都不能更新,因为它可能会破坏某个东西。


共享部件的好处是一致性保证。


现在,如果我们共享所有的东西,我们就是用复杂性来换一致性。这种一致性是不可维护的,因为复杂性会在每个角落引入 Bug。


问题的根源在于“依赖地狱”。下图很好地说明了这一点。



简而言之,如果一切都相互依赖,那么我们就会有依赖问题。仅仅更新一个方框就会影响整个系统。一致吗?确实。简单的?绝不。


微前端只是 Web 端的


为什么只是 Web?诚然,到目前为止,我们接触到的主要是 Web,但其概念和想法可以应用于任何类型的应用程序(移动应用、客户端应用……甚至是 CLI 工具)。在我看来,微前端只是“插件架构”的一个花哨叫法。不过,插件接口如何设计,以及运行使用插件的应用程序需要具备什么条件,这就是另外一回事了。


下图显示了一个非常通用的插件架构,来自Omar Elgabry



通用插件架构


该架构并没有在哪里运行的概念。它既可以在手机上运行,也能在 Windows 上运行,甚至还能在服务器上运行。


微前端需要大型团队


为什么?如果解决方案超级复杂,那么我肯定会找一个简单的。有些问题需要复杂的解决方案,但好的解决方案通常是简单的。


根据场景的不同,它甚至可能不需要一个分布式团队。拥有分布式团队是采用微前端的首要原因之一,但这不是唯一原因。另一个很好的理由是特性的粒度。


如果从业务的角度来看微前端,那么你就会发现,拥有启用和关闭特定特性的能力是很有意义的。针对不同的市场,使用不同的微前端。回到一个简单的权限模式,这是有意义的。不需要编写代码来根据特定条件打开或关闭某些东西。所有这些都留给公共层,可以根据(可能是动态的)条件激活或停用。


这样,不能(或不应该)使用的代码也不会被交付。虽然这不应该是一个保护层,但它肯定是一个便捷(和性能)层。用户不会感到困惑,因为他们看到的是他们能做的。他们看不到没有交付的功能,所以没有字节浪费在不可用的代码上。


微前端无法调试


对于任何类型的实现(或供讨论的底层架构),开发经验都可能遭到削弱。应对这种情况的唯一方法是开发人员优先。实现中的第一原则应该是:使调试和开发成为可能。采用标准的工具。


有些微前端框架根本不接受这一点。有些需要在线连接、专用环境、多重服务……这不应该是标准,也绝不是常态。


微服务需要微前端(或反过来)


解耦的模块化后端可能为解耦前端打下了一个很好的基础,但通常情况下,情况并非如此。后端单体,前端模块化,也是完全可行的,例如,为简化个性化可能就要结合授权、权限和市场。


实际上,同样,微服务后端并不能证明适合将类似的模式应用于前端。许多微服务后端都是由单用途的应用程序操作的,它们的功能没有增加,只是外观发生了改变。


微前端需要单存储库


我已经读到过好几次,要创建一个微前端解决方案,就需要利用单存储库,最好使用像 Lerna 这样的工具。我不认可这一点。当然,单存储库有一些优点,但也有明显的缺点。


虽然有一些微前端框架需要联合 CI/CD 构建,但大多数都不需要。联合 CI/CD 构建通常会导致单存储库,因为其设置要简单得多。但对我来说,这是单体重新打包。如果你在单存储库上进行联合构建,那么你就失去了让微前端富有吸引力的两个非常重要的优点:


  1. 独立部署

  2. 独立开发


不管怎样,如果你看到微前端解决方案需要单存储库:那样做就行。一个精心设计的单体系统可能会更好,它不会有分布式系统的所有问题。


结论


微前端技术并不适合所有人。我不认为微前端是未来的发展趋势,但我也相信它们在未来会发挥重要作用。


原文链接:


https://blog.bitsrc.io/11-popular-misconceptions-about-micro-frontends-d5daecc92efb


2020 年 10 月 11 日 09:002308
用户头像

发布了 328 篇内容, 共 142.2 次阅读, 收获喜欢 681 次。

关注

评论 1 条评论

发布
用户头像
赞~感同身受
2020 年 10 月 12 日 14:21
回复
没有更多了
发现更多内容

极客时间架构 1 期:第4周 系统架构 - 命题作业

Null

设计一套RPC框架并非易事

架构师修行之路

分布式 微服务 RPC

第四周作业 (作业二)

Geek_83908e

极客大学架构师训练营

架构师训练营 - 命题作业 - 第四周

徐时良

第四周作业

fmouse

极客大学架构师训练营

第四周作业 (作业一)

Geek_83908e

极客大学架构师训练营

极客时间架构 1 期:第 4 周 系统架构 - 学习总结

Null

手把手教你如何在Oasis Second State 社区黑客马拉松获得 50 ROSE

Michael Yuan

区块链 智能合约 以太坊 hackathon

第四周作业

TheSRE

极客大学架构师训练营

浅析 synchronized

朱华

Java 并发编程 synchronized

第三周作业

m

第10周学习总结

Vincent

极客时间 极客大学

第四周学习总结

alpha

极客大学架构师训练营

架构师 1 期 - 系统架构作业

ltl3884

极客大学架构师训练营

[架构师训练营第 1 期] 第四周学习总结

猫切切切切切

极客大学架构师训练营

「架构师训练营」第四周课后练习

L

高并发系统设计负载均衡架构

架构师修行之路

负载均衡 分布式 微服务

架构师训练营 - 第四周 - 作业一

行者

Q3结束的一点小感悟:谋篇者布全局,执行者拿结果

邓瑞恒Ryan

自我管理 创业心态 运营 运营管理

设计模式

Zzzz

极客大学架构师训练营

「架构师训练营」第四周课后练习

L

极客大学 - 架构师训练营 第四周

9527

4节课带你光速入门微信小程序开发-0简介

newbmiao

光速入门小程序开发 云开发 换个头像

第四周总结

fmouse

极客大学架构师训练营

手把手教你AspNetCore WebApi:认证与授权

AI代笔

Token ASP.NET Core JWT web api

第10周作业

Vincent

极客时间 极客大学

架构师训练营第1期第4周作业

业哥

极客大学架构师训练营

[架构师训练营第 1 期] 第四周命题作业

猫切切切切切

极客大学架构师训练营

架构师训练营1期第4周作业

木头发芽

架构师训练营 - 第四周 - 作业二

行者

【架构笔记之系统架构】架构师训练营第1期第4周

业哥

极客大学架构师训练营

InfoQ 极客传媒开发者生态共创计划线上发布会

InfoQ 极客传媒开发者生态共创计划线上发布会

对微前端的11个错误认识-InfoQ