微前端不同场景的解决方案和框架
前言
微前端最早由ThoughtWorks在2016年提出,其主要思想是在前端引入类似后端微服务架构的理念,将庞大的巨石应用拆分成多个独立的应用(以下称微应用)。每个独立应用都可独立开发、测试和部署,然后在通过一个容器应用(以下称主应用)将所有独立应用组合起来呈现个用户。
实现微前端的方式有很多种,我们熟知的iframe其实就属于微前端,其具有自带沙箱隔离,开发分离等优点,但是同时也有很多额外的问题,重复加载脚本、SEO较差、多个滚动条等等问题导致其无法广泛应用。而现代SPA框架的兴起给微前端带来了新的福音。
微前端的想法是将前端单体分解为许多更小、更易管理的片段。每个团队可以端到端地拥有自己的功能,可以在自己的代码库中工作,可以独立发布版本,可以不断进行小的增量升级,还可以通过 API 与其他团队集成,以便他们可以一起组建和管理页面及应用程序。
微前端有很多方法,从智能的构建时组件集成,到使用自定义路由的运行时集成等等。
如何构建微前端?
这个 问题没有确切答案。和微服务一样,并不存在适用于所有人的单一方法,也没有已确立的业界标准。
相比微服务实现,微前端不仅在实现细节上存在差异,而且在所有的细枝末节上均有所不同。因此需要区分主要使用场景。一些服务端框架也支持客户端组装,反之依然。
客户端框架
客户端微前端的可选择范围很广。其中部分支持服务端渲染。
客户端构成
下列框架实现了这种( 或类似 的)模式:
服务端框架
服务端框架有多种选项。但其中一些只是用于 express 的软件库或框架;还有一些以服务形式提供,需加载到用户的基础架构中。
服务端构成
下列框架实现这种( 或类似 的)模式:
Helper 库
还可考虑一些帮助(helper)库。这些帮助库或是提供共享依赖、路由事件的基础架构,或是将不同的微前端及其生命周期组织起来 。
下例通过 Import Maps 或打包特定 Chunk 实现对共享依赖的处理。
使用 Import Maps 共享依赖。
下面的库可用于削减模板代码:
微前端框架
1、Bit
Bit 容许你从独立的组件组建和管理前端。它可能是清单上最受欢迎的、可用于生产(production-ready)的解决方案。
如果查看 bit.dev 主页,你会发现它由很多独立的组件构成。这些组件由不同团队,在不同代码库中构建,并最终集成在一起,创造了一个紧密结合的产品。Bit CLI 是广泛流行的工具,用于组件驱动开发。使用 Bit,你可以将独立的组件构建、集成和组合到一起。
尽管人们通常将微前端视为在运行时发生的组合,但 Bit 可以让开发人员在构建时高效地组合前端,以享受两全其美的优势:“传统单体式前端”的安全性和健壮性,以及微前端的 简单性 和 可伸缩性。使用 Bit,在与其他团队合作同时,不同的团队可以独立构建、发布和公开其组件,这样就可以将 Web 开发过程转变为功能和组件的模块化组合。
除了 用于组件驱动开发的 OSS 工具 外,Bit 还为团队提供了一个 云平台,该云平台使得团队可以构建变更并在组件上进行协作,可以高效地管理和扩展开发过程,同时保持所有团队完全独立,团队可自主交付。为了确保每个前端都有自己独立且快速的构建流程,Bit 还提供了独特的 CI/CD 流程,该流程为 100% 组件驱动,这意味着不同的团队可以安全地集成更改,而不必等待,争夺主控权或打破任何东西。开发人员可以在所有受影响的应用程序中持续和安全地将更改传播到组件。
作为结果,通过 简单的解耦代码库、自治团队、小型定义良好的 API、独立的发布管道 和 持续增量升级,增强了工作流程。
如果你的团队使用组件来开发软件,并且正在寻找一种可以在大型应用程序上解锁微前端和模块化工作的解决方案,请务必查看 Bit 的 OSS 工具和平台,这可能正是你所需要的。
官网:https://bit.dev/
Github:https://github.com/teambit/bit Start:13.1k
2. Webpack 5 和 Module Federation
多个单独的构建最后要形成一个应用程序。这些单独的构建不应相互依赖,因此可以单独开发和部署。
Module Federation 是 Zack Jackson 发明的 JavaScript 架构,Zack Jackson 随后提出为其创建一个 Webpack 插件。Webpack 团队提供帮助将该插件引入了 Webpack 5。
简而言之,Module Federation 允许 JavaScript 应用程序在运行时从另一个应用程序动态导入代码。模块将构建唯一的 JavaScript 入口文件,其他应用程序可以通过设置 Webpack 配置项来下载该入口文件。
它还通过启用依赖关系共享来解决代码依赖关系和包大小增加的问题。例如,如果你要下载一个 React 组件,那么你的应用程序不会两次导入 React 代码。模块将自动使用你已有的 React 源,仅额外导入组件代码。最后,你可以使用 React.lazy 和 React.suspense 提供后备功能,以确保当导入的代码由于某种原因失败后,不会因构建失败而影响用户体验。
这个架构释放了构建微前端的巨大潜力。
项目地址:https://webpack.js.org/concepts/module-federation/
EMP
国内利用它开发的框架EMP – EMP是由欢聚时代业务中台自主研发的最年轻的单页微前端解决方案。
EMP特性:
- 基于
Webpack5
的新特性Module Federation
实现,达到第三方依赖共享,减少不必要的代码引入的目的。 - 每个微应用独立部署运行,并通过cdn的方式引入主程序中,因此只需要部署一次,便可以提供给任何基于
Module Federation
的应用使用。并且此部分代码是远程引入,无需参与应用的打包。 - 动态更新微应用:
EMP
是通过cdn
加载微应用,因此每个微应用中的代码有变动时,无需重新打包发布新的整合应用便能加载到最新的微应用。 - 去中心化,每个微应用间都可以引入其他的微应用,无中心应用的概念。
- 跨技术栈组件式调用,提供了在主应用框架中可以调用其他框架组件的能力(目前已支持互相调用的框架及使用方式请参阅官方文档)。
- 按需加载,开发者可以选择只加载微应用中需要的部分,而不是强制只能将整个应用全部加载。
- 应用间通信,每一个应用都可以进行状态共享,就像在使用npm模块进行开发一样便捷。
- 生成对应技术栈模板,它能像
create-react-app
一样,也能像create-vue-app
一样,通过指令一键搭建好开发环境,减少开发者的负担。 - 远程拉取ts声明文件,
emp-cli
中内置了拉取远程应用中代码声明文件的能力,让使用ts开发的开发者不再为代码报错而烦恼。
细心的小伙伴应该发现,EMP
除了具备微前端的能力外,还实现了跨应用状态共享、跨框架组件调用的能力,这是现有框架所不具备的优秀特性!
Github:https://github.com/efoxTeam/emp
3. Single SPA
Single SPA 将自己定义为一种“前端微服务 Javascript 框架”。简言之,它将生命周期应用于每个应用程序。每个应用程序都可以响应 url 路由事件,并且知道如何从 DOM 引导,加载和卸载自身。传统 SPA 和 Single SPA 应用程序之间的主要区别在于它们能够与其他应用程序共存,并且它们各自没有自己的 HTML 页面。
因此,如果你希望将不同的前端或框架整合到一个 DOM 中,并希望在运行时进行集成,请查看这个有趣的实验。
官网:https://single-spa.js.org/
Github:https://github.com/single-spa/single-spa
qiankun
qiankun 是一个基于 single-spa 的微前端实现库,旨在帮助大家能更简单、无痛的构建一个生产可用微前端架构系统。
qiankun 孵化自蚂蚁金融科技基于微前端架构的云产品统一接入平台,在经过一批线上应用的充分检验及打磨后,将其微前端内核抽取出来并开源,希望能同时帮助社区有类似需求的系统更方便的构建自己的微前端系统,同时也希望通过社区的帮助将 qiankun 打磨的更加成熟完善。
qiankun 的核心设计理念:
简单
由于主应用子应用都能做到技术栈无关,qiankun 对于用户而言只是一个类似 jQuery 的库,你需要调用几个 qiankun 的 API 即可完成应用的微前端改造。同时由于 qiankun 的 HTML entry 及沙箱的设计,使得子应用的接入像使用 iframe 一样简单。
解耦/技术栈无关
微前端的核心目标是将巨石应用拆解成若干可以自治的松耦合微应用,而 qiankun 的诸多设计均是秉持这一原则,如 HTML entry、沙箱、应用间通信等。这样才能确保子应用真正具备 独立开发、独立运行 的能力。
官网:https://v1.qiankun.umijs.org/zh/
Github:https://github.com/umijs/qiankun
4. Piral
Piral 的目标是让你可以使用微前端轻松构建门户应用程序。你可以使用 Piral 创建模块化前端应用程序,并利用微前端体系结构在运行时使用称为 pilets 的解耦模块进行扩展。用户可以独立开发一个 pilet,并附带必要的代码以及所有其他相关资产。这是一个现场演示:
Piral 所要求的前提条件相当宽松,开发人员仅需要安装喜欢的编辑器、终端、网络浏览器和 Node.js 即可。开发者可以在本地开发机的仿真器中执行和调试 Piral instance(应用程序外壳)和 piltes(功能模块)。
Github:https://github.com/smapiot/piral
5. OpenComponent
Open Component(简称 OC)项目宣布其目标是“前端世界中的无服务器”。更具体地说,OC 旨在成为一个一站式微前端框架,从而使其成为一个丰富而复杂的系统,其中包括从组件处理到注册表、再到模板、甚至包括 CLI 工具。OpenComponents 有两个部分:
- components 是同构代码的小单元,主要由 html、javascript、css 组成。它们可以选择包含一些逻辑,从而允许服务端的 node.js 应用去组建用于呈现视图的模型。在渲染之后,它们就是纯 html 片段,可以插入到任何 html 页面中。
- consumers 是网站或微型网站(所有小型可独立部署的网站,这些网站均通过前门服务或路由机制连接)。这些网站需要在其网页中呈现部分内容的组件。
Github:https://github.com/opencomponents/oc
6. Liugi
Luigi 是一个微前端 JavaScript 框架,你可以使用它创建由本地和分布式视图驱动的管理用户界面。Luigi 允许 Web 应用程序与应用程序包含的微前端进行通信。为了确保通信顺利进行,你可以配置路由、导航、授权和 UX 元素等设置。
Luigi 由 Luigi Core 应用程序和 Luigi 客户端库组成。他们使用 postMessage API 在核心应用程序和微前端之间建立安全的通信。想获取更多信息,请自行前往查看。
Github:https://github.com/SAP/luigi
7.FrintJS
FrintJS 是“用于构建可伸缩和响应式应用程序的模块化 JavaScript 框架”。你可以使用它加载来自不同 bundlers 的应用程序,为应用程序提供结构,并处理诸如路由、依赖关系等问题。该项目可通过附加的软件包支持 RN 和 Vue,但文档和测试大多数是针对 React 的。
Github:https://github.com/frintjs/frint
8、PuzzleJS
PuzzleJS 是“用于可扩展和快速建站的微前端框架”。你可以使用它创建相互对话的网关和店面项目。它的灵感来自 Facebook 的 BigPipe,朝着微前端的方向发展。
PuzzleJs 提供诸如创建网关或店面(彼此独立)的功能,并提供配置文件将它们连接。你可以使用它在编译时将 html 模板编译为 javascript 函数。此操作完全独立于请求,因此 PuzzleJ 可以使用此功能发送第一个块。它也是 SEO 友好的,在服务端进行准备和渲染。而且,当片段所需的 api 出现故障时,PuzzleJs 可保证其他页面片段仍正常工作。
Github:https://github.com/puzzle-js/puzzle-js
微前端的下一步发展
虽然 有些人觉得 Module Federation 之类的帮助库很好用 ,但多数人还是会继续用原来的解决方案 。好的一面是,有很多不受大厂商控制的框架可以用来轻松编写代码 。但至少从技术上看,微前端依然缺少便于解决方案互通的通用标准。
另一个问题是,微前端的社区接受度和采用率仍显不足。
尽管微前端模式已经有一定知名度,但是社区中大多数人仍对其存疑。
究其原因,其一是微服务被视为一种后端设计的最佳实践和标准,但并未当作是一种新的, 可用于特定场景的工具。显然这并不是人们当初想的那样,所以微前端也不应该被视为灵丹妙药。
小结
微前端现有解决方案的可用数量及其在全球许多项目中的用途都发出了强烈的信号:微前端已经随时可以使用!我建议,在实际开始大型 / 生产级项目之前, 先考察各种模式和解决方案。
我想了解大家的观点及原因,对微前端持喜爱、可容忍态度,还是弃若敝屣?