对微前端的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:00 2008
用户头像

发布了 298 篇内容, 共 132.9 次阅读, 收获喜欢 592 次。

关注

评论 1 条评论

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

来聊一聊Linux常用命令(第二篇)~

程序员的时光

Linux

上下文切换的资源消耗

麻瓜镇

多线程 操作系统

回“疫”录(14):跨越时空的相同选择

小天同学

疫情 回忆录 现实纪录 感恩

0风险高收益的投资

Neco.W

学习 投资 自我提升

TensorFlow On Flink 原理解析

Apache Flink

大数据 flink 流计算 实时计算 大数据处理

数据中台的思考

杜伟

自助设备系列——菜品的自助识别结算

孙苏勇

人工智能 产品 行业分析 智能设备

MySQL 实现排名

黄大路

数据挖掘 MySQL 数据库 sql 数据分析

什么是实时数仓,与离线数仓的区别是什么?

程序员小陶

大数据 数据仓库 实时数仓

必要的革命:深层学习与可持续创新

这小胖猫

好书推荐 持续学习 创新 系统性思考 价值观

并发编程如何才能不再头疼:iOS中的协程

超越杨超越

ios 协程 coobjc ucontext

打造高颜值 iTerm2

marsxxl

macos Mac 终端 terminal

笔记:《如何系统思考》之系统基模

wiflish

思维方式

01-Taro打造hello-world应用

页面仔小杨

小程序 微信小程序 taro

真特么是个好东西

非著名程序员

程序员 效率工具 写作

阅读有术:怎么记住书中的内容

子不语

学习方法 方法论 读书方式

高仿瑞幸小程序 07 为你推荐模块

曾伟@喵先森

小程序 微信小程序 前端

SpringBoot前后端分离项目,集成Spring Security(完整版)

读钓

Java spring Spring Boot spring security

概念有时候很坑

伯薇

抽象 思考力 沟通 概念

Kafka系列第6篇:消息是如何在服务端存储与读取的,你真的知道吗?

z小赵

Java 大数据 kafka 实时计算

为什么我们要工作

黄大路

思考 工作

Kylin 在互联网公司的实践合集

程序员小陶

大数据 kylin

一个关于成长的经验公式

oldj

成长

谈谈控制感(1):控制感与职业方向选择

史方远

ONTAP 9 巡检模板

HU

CentOS 6 升级 OpenSSH 8.1p1

wong

centos openssh

Rust安装注意事项

邱张华

rust 镜像源 diesel

嫌 OSS 查询太慢?看我们如何将速度提升 10 倍!

苏锐

大数据 性能优化 数据湖 OSS 对象存储

在线修改主从复制选项

Simon

MySQL

引入了绩效管理,团队反而一天不如一天了?(二)

无箭的丘比特

团队管理 企业文化 绩效

实时数仓 | 你需要的是一款强大的 OLAP 引擎

程序员小陶

大数据 OLAP

万亿规模下美团命名服务的演进与业务赋能

万亿规模下美团命名服务的演进与业务赋能

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