# 微前端

## 微前端定义

微前端（Micro Frontends）是一种通过将前端应用程序拆分成小型、独立的功能单元来构建复杂的用户界面的技术架构模式。它的核心思想是将前端应用程序分解成多个独立的部分，每个部分可以由不同的团队独立开发、测试、部署和维护，最终集成到一个统一的用户界面中。

### 微前端带来的问题

细想一下：通过微前端常见的解决方案，其实我们是可以归纳一些微前端存在的问题，比如 `样式冲突、消息通信、脚本互斥、公共依赖加载`等问题；所以 `微前端框架` 就因为这些问题应运而生了。

## 1. 应用隔离

应用隔离主要分两种情况：

- 一种是 `主应用与微应用`之间的隔离；
- 一种是 `微应用与微应用`之间的隔离；

应用间所隔离的主要是 `Javascript 的沙箱隔离`和 `CSS 的样式隔离`；

### CSS 样式隔离

由于在微前端场景下，不同技术栈的子应用会被集成到同一个运行时中，所以我们必须在框架层确保各个子主应用之间不会出现样式互相干扰的问题；

例如：一个团队的微应用的样式表为 `h2 { color: black; }`，而另一个团队的微应用则为 `h2 { color: blue; }`，而这两个选择器都附加在同一页面上，就会冲突；

为了避免这个问题，常见的解决方案有：

- 严格的命名约定，例如 BEM；
- CSS Module；
- 各种 CSS-in-JS 库；
- shadow DOM；

### Javascript 沙箱隔离

每当微应用的 JavaScript 被加载并运行时，它的核心实际上是对全局对象 Window 的修改以及一些全局事件的改变，例如 jQuery 这个 js 运行后，会在 Window 上挂载一个 window.$ 对象，对于其他库 React，Vue 也不例外。

为此，需要在加载和卸载每个微应用的同时，尽可能消除这种冲突和影响，最普遍的做法是采用沙箱机制（SandBox）；

**沙箱机制的主要特性如下图：**

![微前端6.png](https://static.www.toimc.com/blog/picgo/2024/06/26/fa8ca15c95d6429293a74101c1dbbf06-tplv-k3u1fbpfcp-zoom-in-crop-mark-1512-0-0-0-b7740a.webp)

**常见实现沙箱的方法：**

- 沙箱快照；
- ES6 的 Proxy 代理；

## 2. 跨应用通信

微前端最常见的问题之一是如何让微应用之间能够**相互通信**。

一般而言，我们建议让微应用之间尽可能少地交流，因为这通常会重新引入我们最初试图避免的那种不适当的耦合代码。也就是说，通常我们只需要`某种程度的跨应用通信`即可。

**常见的通信方式：**

- 使用 `自定义事件通信`，是降低耦合的一种好方法；
- 可以考虑 React 或 Vue 应用中常见的 `全局 state store 机制`；
- `发布-订阅（pub/sub）模式`的通信机制；
- 使用 `地址栏`作为通信机制；

正式因为这些问题的存在，所以就导致了一系列的微前端框架出现，下面主要给大家介绍下全世界范围内比较有名气的一些框架。

# 微前端框架

## 1. Single-spa

[Single-spa](https://single-spa.js.org/) 是最早的微前端框架，兼容多种前端技术栈；

概念：Single-spa 是一个将多个单页面应用聚合为一个整体应用的 `JavaScript 微前端框架`；

我们都知道 `spa 应用` 的理念是让独立的应用程序组成一个完整的页面，`Single-spa` 并不用依赖于单个框架和每个特性，而是你可以在不同的新框架随意使用；

简单来说就是一个聚合，使用这个库可以让你的应用可以 `使用多个不同的技术栈（vue、react、angular等等)`进行同步开发，最后使用一个公用的路由去实现完美的切换；

**优点：**

- 敏捷性 - 独立开发、独立部署，微应用仓库独立，前后端可独立开发，部署完成后主框架自动完成同步更新；
- 技术栈无关，主框架不限制接入应用的技术栈，微应用具备完全自主权；
- 增量升级，在面对各种复杂场景时，我们通常很难对一个已经存在的系统做全量的技术栈升级或重构，而微前端是一种非常好的实施渐进式重构的手段和策略
- 更快交付客户价值，有助于持续集成、持续部署以及持续交付；
- 维护和 bugfix 非常简单，每个团队都熟悉所维护特定的区域；

**缺点：**

- 无通信机制
- 不支持 Javascript 沙箱
- 样式冲突
- 无法预加载

> 正是因为有了 `Single-spa`，才让大部分微前端框架得以出现，所以以下所讲的微前端框架几乎都拥有 `Single-spa` 的优点。

## 2. Qiankun

Qiankun 是一个基于 single-spa ，阿里系开源的微前端框架，旨在帮助大家能更简单、无痛的构建一个生产可用微前端架构系统。

**设计理念：**

- `由于主应用微应用都能做到技术栈无关`，qiankun 对于用户而言只是一个类似 jQuery 的库，你需要调用几个 qiankun 的 API 即可完成应用的微前端改造。
- 同时由于 qiankun 的 HTML entry 及沙箱的设计，使得微应用的接入 `像使用 iframe 一样简单`。
- 微前端的核心目标是 `将巨石应用` 拆解成若干可以 `自治的松耦合微应用`，而 qiankun 的诸多设计均是秉持这一原则，如 HTML entry、沙箱、应用间通信等。这样才能确保微应用真正具备 `独立开发、独立运行` 的能力。

**qiankun 的在线案例：**

1. tech.antfin.com/partners
2. www.zstack.io/

**优点：**

- 📦 **基于 single-spa** 封装，提供了更加开箱即用的 API。
- 📱 **技术栈无关**，任意技术栈的应用均可 使用/接入，不论是 React/Vue/Angular/JQuery 还是其他等框架。
- 💪 **HTML Entry 接入方式**，让你接入微应用像使用 iframe 一样简单。
- 🛡 **样式隔离**，确保微应用之间样式互相不干扰。
- 🧳 **JS 沙箱**，确保微应用之间 全局变量/事件 不冲突。
- ⚡️ **资源预加载**，在浏览器空闲时间预加载未打开的微应用资源，加速微应用打开速度。
- 🔌 **umi 插件**，提供了 @umijs/plugin-qiankun 供 umi 应用一键切换成微前端架构系统。
- 🔥 **社区较为活跃**，维护者也较多，有问题会及时得到响应；

**缺点：**

- 可能对一些 jQuery 老项目支持性不是特别好；
- 安全和性能可能会有影响，具体取决于项目；
- 对 eval 的争议，`eval`函数的安全和性能是有一些争议的：MDN的eval介绍；

> 另外阿里系还有另外两款微前端框架：
>
> - Icestark，是一个面向大型系统的微前端解决方案；
> - Alibaba Cloud Alfa，是在阿里云控制台体系中孵化的微前端方案，定位是面向企业级的微前端体系化解决方案；
>
> 这两款框架相较于 `Qiankun` 来讲社区活跃度以及 demo 较少，所以不太推荐使用该框架，大家了解即可。

## 3. Micro App

Micro App 是京东出的一款基于 `Web Component` 原生组件进行渲染的微前端框架，不同于目前流行的开源框架，它从组件化的思维实现微前端，旨在降低上手难度、提升工作效率。

它是目前市面上接入微前端成本最低的框架，并且提供了 `JS沙箱、样式隔离、元素隔离、预加载、资源地址补全、插件系统、数据通信` 等一系列完善的功能。

**优点：**

- **简单**：只需一行代码，实现微前端，如此简单；
- **无关技术栈**：任何框架皆可使用；
- 静态资源补全；
- JS沙箱；
- 样式隔离；
- Qiankun 微前端框架的优势他都有；

## 4. EMP

EMP 是欢聚时代基于 `Webpack5 Module Federation` 搭建的微前端方案；

由于是基于 `Webpack5 Module Federation` 来搭建的，所以相对与微前端跨框架、状态解决方案混淆比较严重，且 EMP 解决的是项目解耦而不是多系统聚合，与 bit（下面讲的） 这种跨项目组件复用平台较为类似；

**优点：**

- 依赖自动管理，可以共享 Host 中的依赖，版本不满足要求时自动 fallback 到 Remote 中依赖；
- 共享模块粒度自由掌控，小到一个单独组件，大到一个完整应用。既实现了组件级别的复用，又实现了微服务的基本功能；
- 共享模块非常灵活，模块中所有组件都可以通过异步加载调用；

**缺点：**

- 无法做到多框架兼容等微前端方案的痛点；
- 基于 **Webpack5 Module Federation**，需要统一 Webpack5 技术；
- 文档资料，社区不够活跃；

## 5. Garfish

Garfish 是由字节跳动开源的一套微前端解决方案，主要用于解决现代 web 应用在前端生态繁荣和 web 应用日益复杂化两大背景下带来的 `跨团队协作、技术体系多样化、应用日益复杂化`等问题，Garfish 已经经过大量的线上应用的打磨和测试，功能稳定可靠。

**框架特性：**

- 🌈 **丰富高效的产品特征**
  - Garfish 微前端子应用支持任意多种框架、技术体系接入
  - Garfish 微前端子应用支持「**独立开发**」、「**独立测试**」、「**独立部署**」
  - 强大的预加载能力，自动记录用户应用加载习惯增加加载权重，应用切换时间极大缩短
  - 支持依赖共享，极大程度的降低整体的包体积，减少依赖的重复加载
  - 内置数据收集，有效的感知到应用在运行期间的状态
  - 支持多实例能力，可在页面中同时运行多个子应用提升了业务的拆分力度
- 📦 **高扩展性的核心模块**
  - 通过 Loader 核心模块支持 HTML entry、JS entry 的支持，接入微前端应用简单易用
  - Router 模块提供了路由驱动、主子路由隔离，用户仅需要配置路由表应用即可完成自主的渲染和销毁，无需关心内部逻辑
  - Sandbox 模块为应用的 Runtime 提供运行时隔离能力，能有效隔离 JS、Style 对应用的副作用影响
  - Store 提供了一套简单的通信数据交换机制
- 🎯 **高度可扩展的插件机制**
  - 提供业务插件满足各种定制需求

**设计理念：**

![d456c7d2235c41daa298aba69ade435f_tplv-em5hxbkur4-noop.png](https://static.www.toimc.com/blog/picgo/2024/06/26/9776ed09547d4ef79856effcf892ce4e-tplv-k3u1fbpfcp-zoom-in-crop-mark-1512-0-0-0-cadd56.webp)

> 另外字节跳动开源的号称`「现代 Web 工程体系」`的 modern.js 也是解决微前端的一个框架，大家感兴趣的可以去官网查看，因为该框架是一整套工程体系解决方案，所以可酌情选择；

## 6. Bit

由国外 bit 开发团队开源的一款跨项目的组件复用平台框架；将独立的组件构建、集成组合到一起去管理；

**优点：**

- 具有传统单体式前端的安全性和健壮性；
- 介接入方式简单、可伸缩性强；
- 通过 简单的解耦代码库、自治团队、小型定义良好的 API、独立的发布管道 和 持续增量升级，增强工作流程；

> 严格意义上来讲 Bit 与微前端有较大的的出入，所以 Bit 较为适合那种使用组件来开发项目，且技术栈较为统一的项目；

## 7. Liugi

Liugi 是国外 SAP 团队开源的一个用于微前端 JavaScript 框架；

Luigi 框架提供了配置选项、API 函数和开箱即用的功能，使迁移到微前端架构更容易。Luigi 为您的所有微前端提供一致的用户导航，确保更好的用户体验。

**优点：**

- 面向未来且可扩展；
- 无关技术栈：任何框架皆可使用；
- 独立团队管理、部署、研发；
- 快速部署新功能和错误修复；
- 更小、更易于管理的代码库；
- 降低维护成本；

## 8. OC（OpenComponent）

Open Component（简称 OC）项目宣布其目标是 `前端世界中的无服务器`。

更具体地说，OC 旨在成为一个 `一站式微前端框架`，从而使其成为一个丰富而复杂的系统，其中包括从组件处理到注册表、再到模板、甚至包括 CLI 工具。

**OpenComponents 有两个部分：**

- components 是同构代码的小单元，主要由 html、javascript、css 组成。它们可以选择包含一些逻辑，从而允许服务端的 node.js 应用去组建用于呈现视图的模型。在渲染之后，它们就是纯 html 片段，可以插入到任何 html 页面中。
- consumers 是网站或微型网站（所有小型可独立部署的网站，这些网站均通过前门服务或路由机制连接）。这些网站需要在其网页中呈现部分内容的组件。

## 9. Piral

Piral 是国外 smapiot 团队研发的一款基于 React 的微前端解决方案，其可以无限制地扩展开发工作、渐进部署并基于无服务器基础架构。

**其定义了两个概念：**

- 一个是 Piral，这是给一个应用的壳子（application shell），其承载着各种应用，当然也包括由pilets构建共享的组件，定义这些应用何时被加载以及何时被集成；
- 另一个是 Pilet，这是一个特殊的模块（feature modules），其承载着不同的一应用，包含着独立的资源，其决定了组件的加载时机。

**优点：**

- 高度模块化
- 多框架兼容
- 支持资源文件的拆分
- 全局状态管理
- 独立开发和部署
- CLI工具

> 相较于国外其它微前端框架，Piral 有更好的社区，文档，团队，如果你还在思考使用哪种微前端框架，Piral 不失为一个不错的选择；

## 10. 其它需要了解的框架

- **Ara Framework**：Ara Framework 是一个使用 Airbnb 的 Hypernova 服务端渲染延伸出的微前端框架，使用会较于局限；
- **Mooa**：Mooa 是一个为 Angular 服务的微前端框架，酌情考虑；
- **ngx-planet**：只支持 Angular 框架，不支持其他 MV* 前端框架，酌情考虑；
- **PuzzleJs**：PuzzleJs 是一个用于可扩展和快速建站的微前端框架。除了 SEO ，它的文档等 demo 都不成熟，酌情考虑；

> 当然以上只是概述了一些比较常见的微前端框架，还有一些较为优秀且开源的，欢迎大家补充；

# 总结

- 如果你的项目是一个后台管理系统且都是最新的 MV* 框架，那么 `Qiankun、Micro App、Garfish、Liugi、Piral` 你都可以选择；
- 如果你的项目需要聚合某些老旧框架（jQuery）的项目，那么 `Qiankun、MicroApp` 都可选择，可优先考虑 `Micro App`；
- 如果你想做一个 SEO 的微前端项目，那么 `Piral、PuzzleJs` 较为适合；

> 当然，其实无论哪种方案都可选择其中的较为符合的框架，但是为了满足自己项目与业务场景，可能需要自己一个一个去踩坑才能实现了。

