「1」微前端 (Miro frontends)

"微前端" 应该是我们 2020 年里听的最多的一个前端技术。现在非常多的大厂都在尝试这个新技术来解决大型前端项目中的问题。

虽然我们前端开发中有模块化(modular)的组件(components),但是它相比后端的 “微服务” 是大有不同的。

在了解 “微前端” 之前,我们先给没有接触过后端的同学科补一下后端的 “微服务” 知识。

微服务是什么?

微服务是一种开发软件的架构和组织方法,其中软件由通过明确定义的 API 进行通信的小型独立服务组成。这些服务由各个小型独立团队负责。

上面的专业术语不好理解的话,我们也可以这么理解。微服务 —— 也就是把单独一个业务写成一个独立的服务,有独立的服务器、接口体系、并且有一个单独的团队进行开发与维护。

就比如,淘宝的订单和用户两个 “模块”。一开始这些模块我们可能都会设计在一起的。这样开发起来需要的开发资源和时间就相对比较小。毕竟微服务不是一个 5 - 6 人团队可以 hold 得住的。

等业务变得非常庞大的时候,随着功能和数据的不断在扩大和延伸。这个时候订单和用户模块都变得非常的复杂。这个时候就需要我们把这两个模块单独的拆离出来开发和维护。因为,如果我们不拆离出来,每次改这些模块的一个小功能,都会涉及很多影响。我们就会发现这个系统越来越难迭代,改一个功能或者 bug 都会开始变得非常的困难。

这个就是为什么后端提出了微服务这个概念,为了解决大型应用的维护难题。把业务解耦、隔离、独立化就是解决方案。

既然后端会遇到系统复杂程度过高的情况,自然前端的业务和交互也会越来越复杂。所以最后前端也需要和后端一起建立 “微服务化” 的体系。

微前端是什么?

微前端的起源和后端一样,就是一个模块因为业务和功能的持续发展,导致模块内容的代码越来越复杂,越来越庞大,同时就会造成与其他业务有不可避免的互相影响的关系。

就是这些模块与模块之间的关系,让我们的系统变得越来越难以维护,大大减低了开发的 “敏捷性”。

那么怎么办呢?我们就让一个大型的 app 的业务,按模块拆分成一个一个小的 “服务” 模块。这些小的模块会与后端的接口一样,放在单独的服务器上运行,同时也会有单独的小团队进行专门的开发和维护。

这种微型的独立前端架构体系和系统就叫做 “微前端”。

每个 “微前端” 应用的开发团队,拥有整个应用的生命周期中的自主性。这就包块独立开发、独立版本号管理、独立测试、独立打包、独立渲染、独立更新、独立部署。

微服务后端可以用python吗 微服务是前端还是后端_微前端是什么

在上面的图中,我们就可以看到微前端在一个研发中心里的组织架构。每一个微前端团队都会负责一个独立的业务模块。每一个模块都会有他们自己的核心业务。与其他业务的功能其实是相对独立的,但是业务的流程上他们就会通过数据流、交互流、接口等方面串联起来。

最终用户所体验到的系统,其实跟我们普通的应用没有什么区别。但是大型应用的开发和维护的角度来看,就获得了非常多的好处。

微前端的好处

  • 自主性 —— 可以对每一个微前端应用进行独立的开发、部署、维护和扩展,而不影响其他微前端应用的功能。
  • 专用性 —— 每个微前端应用都是针对一组功能而设计的,并专注于解决特定的问题。如果开发者逐渐将更多的代码增加到一项微前端应用当中,从而让这个微前端应用变得复杂时,那么我们可以将其再次拆分成多项小的微前端应用。
  • 敏捷性 —— 微前端是由若干个小型独立团队形成的一个组织,这些团队负责自己的微前端应用。每个团队在小型而易于理解的环境中进行开发,并且可以更独立,更快速地工作。这个缩短了开发周期的时间。
  • 灵活扩展 —— 通过微前端化应用,我们可以独立扩展组件和功能来满足其他应用的需求。这使团队能够适当调整基础设施需求,准确的衡量功能成本,并在服务需求激增时保持可用性。
  • 轻松部署 —— 微前端支持持续集成和持续交付,可以轻松和放心的尝试新的想法,并可以在无法正常运行时独立回滚某一个应用。由于微前端应用直接都是独立的,所以问题只会发生在自己的应用当中,所以我们可以大胆的试验,更轻松地更新代码,并缩短新功能的上线时间。
  • 技术自由 —— 微前端架构不遵循 “一刀切” 的方法。团队可以自由选择最佳的工具或者框架来解决他们的具体问题。也就是说一个微前端应用可能是用 Vue,然后另外一个可能是用 React 也不是不可以的。因此,构建微服务的团队可以自行选择最佳的工具或者框架。
  • 可重复使用 —— 将前端应用划分成明确定义的模块,让团队可以将功能用于多种目的。专为某项功能编写的前端模块可以用作另一项功能的构建模块。这样应用程序就可以自行引导,因为开发者可以创建新的功能,而无需从头开始编写代码。
  • 弹性 —— 前端应用独立增加了应用程序应对故障的弹性。在整体式架构中,如果一个组件出现故障,可能导致整个应用程序无法运行。通过微前端的拆分架构,应用程序可以通过降低功能而不导致整个应用程序崩溃来处理总体服务故障。

微前端案例

我们了解了微前端是什么,并且它有什么用。那么我们来看看一个微前端在实际开发场景中是怎么样的。

这里幻想一下,我们有一个博客的主页。主要的功能就是为了展示我们的文章内容。当然一个博客其实很简单,在正常开发场景下,也不会给它做微前端的架构设计。

但是如果我们真的想把它做的更强大,那也是可以的:

  • 首先当用户进入我们的首页,可以看到文章的列表,并且用户可以通过关键词来搜索文章。同时也可以通过分类、标签来搜索。更复杂一点的话,我们还可以根据阅读量,热度(通过算法计算热度)来排序和搜索。
  • 每一篇文章必然会有一个详情页,每个详情页都需要展示文章的详细文本。如果我们想加大难度的话,我们还可以根据标签和用户日常的文章浏览记录,来推算用户会对其他什么文章感兴趣。这个时候我们就可以加入相关推荐的文章列表了。
  • 博客必然就会有博主的介绍页(About)、文章分类页(Categories)和文章标签页(Tags)。

当然这个还不是很复杂,但是当我们继续往这个博客平台加入更多的功能,比如最后做成 CSDN、掘金、知乎这样的平台的时候,那么微前端就有必要了!

微前端集成方法

好,如果真的有那么一天,我们变成一个很大的博客平台。那么我们要怎么运用微前端呢?其实集成方法有很多种:

  • 服务器端模板组合 (Server-side template composition)
  • 构建时集成 (Build-time integration)
  • 通过 iframes 在运行时集成 (Run-time integration via iframes)
  • 通过 JavaScript 在运行时集成 (Run-time integration via JavaScript)
  • 通过 Web 组件在运行时集成 (Run-time integration via Web Components)

我们这里就不一一去讲解了,如果我们真的哪一天遇到一个场景需要我们用微前端去解决我们的技术难题时。我们再去深入学习微前端即可。这里主要的目的是让我们了解清楚微前端是什么能解决什么,它是怎么解决的即可。

其实所有的集成方法,都围绕着一个很自然的设计模式 —— 一个应用里面的每一个页面都是一个 “单独的” 微前端应用。而在每一个页面中都会有一个“单独的应用容器(single container application),而它的作用就是:

  • 渲染页面公共头部(headers)和脚步(footers)
  • 解决 “横切关注点(Cross-cutting concern)”,比如身份验证和导航
  • 把多个微前端应用放在一个页面之中,并且告诉每一个微前端应用在什么时候和在哪里渲染到页面上。

大概的页面设计如下:

微服务后端可以用python吗 微服务是前端还是后端_微前端是什么_02

注意我们这里只讲到微前端的皮毛,其实微前端最核心并不在前端,更多的难点都是在 “云服务器”。如果没有服务器架构、部署、测试和后端接口等等的支撑,微前端是很难以实现的。所以在一般公司的应用场景,其实根本用不上微前端。如果用不上,了解到这里其实已经可以了。到用得上的时候再去深挖更多的知识即可!


「2」原子设计 (Atomic Design)

原子设计也是在 2020 年里面提到的非常多的一个概念。不过这个更多只是一个概念,并不是一个纯方法论。

这个概念是 Brad Frost 提出的,他用化学中的原子组成来分析和拆解一个 web 应用的组成成分。里面包换原子(Atoms)、分子(Molecules)、生物体(Organisms)等。

比如一个搜索分子(Search Molecule)就是由 input-text(输入文本)+ button(按钮)+ label(标题)等原子所组成。然后这些分子组合起来就会变成一个生物体(Organism)。

而生物体(Organism)就会生存在我们页面的布局模版之中,而这些就可以具体化成一个页面,最后显示给到我们的用户。

Brad Frost 把我们前端的组件和界面的设计抽象成化学中的原子组成结构。让我们更加清晰的去理解一个页面、一个组件、一个元素的组成方式。

其实这个概念,可以让我们用一个全新的角度去看待模块化 UI(modular UI)。这种思维方式让我们更深入的理解一个组件的作用和 API,从而在设计组件的时候会更加的清晰和高效。

一个简单易懂的表示图:

微服务后端可以用python吗 微服务是前端还是后端_什么是微前端_03

原子(Atom)是什么?

原子是物质的基本组成部分。而在组件设计中,原子就是一个组件的最小元素单位,一个组件都是用多个原子所组成的。

在 web 界面中,原子就可以是:HTML 标签

  • 表格的 label
  • 输入框 input
  • 按钮 button

微服务后端可以用python吗 微服务是前端还是后端_什么是微前端_04

原子单独使用是没有任何意义的,一般都是需要组合其他原子一起使用才能真正发挥它们的作用。

分子(Molecule)是什么?

当我们把原子(Atoms)结合在一起时,事情开始变得更加的有趣。分子(Molecule)是一组结合在一起的原子,是化合物中最小的基本单位。每一个分子都有自己的特性,是我们设计系统的支柱(Backbone)。

比如,一个表格标题、输入框、按钮等元素,它们单独使用时没有太大用处的。但是如果我们把它们组合在一起,变成一个表格。这个时候它们就可以使用了。

微服务后端可以用python吗 微服务是前端还是后端_微前端和原子设计_05

在我们用原子组合分子时,我们需要遵循一个原则:“只做一件事,并且做好”。(这个听起来是不是有点像设计模式里面的:“单一职责”?是的,就是这个意思。)虽然分子可能很复杂,但根据经验,他们相对而然都是一些简单的原子而组成的,主要是为了可复用性而生。

生物(Organism)是什么?

分子可以作为我们组建界面的积木。我们可以把分子组合在一起来建立一个生物体(也就是我们的一个界面)。生物体是用一组分子组合而成的,而组成的生物体是界面的其中一部分,它有相对复杂,独特的特性。

微服务后端可以用python吗 微服务是前端还是后端_微前端是什么_06

就比如上图,我们在组合了一个网页 logo 部分的分子。然后我们把搜索分子和 logo 分子再组合在一起,就变成了界面上头部(生物体)的部分(header organism)。

这个就会开始变得越来越有趣了,生物体不是一个固定的组件,它是用多个分子所组合而成。不同的生物体可能存在使用相同的分子或者原子,但是他们的作用都是有所不同的。

就比如,我们的 logo 和文章图片两个不同的分子,他们都使用了 img 图片标签这个原子。但是这个 img 原子是放在了两个不同职责的分子里面,一个是用在头部作为 logo 展示的,一个是用在文章列表用来展示图片的。

所以在组建分子和用分子组件生物体的时候,我们创建的组件必须是独立的、可移植、可重用的

模版(Templates)

有了分子组成的生物体(Organism)后, 我们就可以用这些生物体来组建我们的界面模版。这里我们就可以打破化学的类比,拥有对用户和最终输出更有意义的东西。

模版主要是由多个生物体缝合在一起而形成的页面。在这里,我们开始看到组件和模块的设计开始融合在一起,可以看到布局之类的东西开始有所体现了。

微服务后端可以用python吗 微服务是前端还是后端_微前端和原子设计_07

模版是非常具体化的,它为所有的这些相对抽象的分子和生物体提供了上下文。模版阶段也是用户可以开始看到设计界面的地方。根据这个设计的创作者 Brad Frost 的使用经验,模版一开始是 HTML 线框,但随着时间的推移,它的保真度会逐渐提高,最终成为可交付的产品。

页面(Pages)

页面(pages)是模版的特定实例。这里,占位符内容被真实的、有代表性的内容所取代,以准确地表现方式描述了用户最终将要看到的内容。

微服务后端可以用python吗 微服务是前端还是后端_微服务后端可以用python吗_08

页面是最真实的,因为它们是最有形态的,它通常是大多数人在开发过程中花最多时间来处理和优化的部分。

页面这个阶段非常的重要,因为这里是我们测试设计系统有效性的地方。在上下文本中查看一切,是我们能够回头来修改我们的分子(Molecules)、生物体(Organism)和模版(Templates)的阶段。

页面也是测试模版变化的地方。例如,我们可能想清楚地表达包含40个字符的标题最终展示到给用户是什么样子的,但是也想演示340个字符是什么样子。当用户的购物车中有一件商品应用了折扣的时候,商品的展示会是怎么样的。这些实际的情况会影响我们如何循环和构建我们的应用。

为什么用原子设计理念?

我们简单理解了原子设计后,我们就可以问问,为什么要用原子设计呢?

其实答案很简单,我们平时去设计一个应用的时候,即使我们没有意识去使用这种思维方式,但是我们一直都是以这种方式在设计的。

原子设计为设计系统提供了一种清晰的方式轮(概念为主),团队成员(开发者、产品经理、设计师等)能够通过实际看到的,摆在他们面前的步骤来更好地理解设计系统的概念。

原子设计赋予我们从抽象到具体的能力。正因如此,我们可以创建促进一致性和可伸缩性的系统,同时在最终的页面中显示内容。

重点是通过组合而不是解耦的方式来构建应用。我们在一开始就创造了一个系统,而不是在事后才去挑选模式。