微前端简介
微前端简介
Techniques, strategies and recipes for building a modern web app with multiple teams that can ship features independently. -- Micro Frontends
微前端是一种多个团队通过独立发布功能的方式来共同构建现代化 web 应用的技术手段及方法策略。
构建一个现代web应用所需要的技术、策略和方法,具备多个团队独立开发、部署的特性。
微前端是将多个前端应用以某种形式结合在一起进行应用。旨在解决单体应用在一个相对长的时间跨度下,由于参与的人员,团队增多、变迁,从一个普通应用演变成一个巨石应用(Frontend Monolith)后,随之而来的应用不可维护的问题。
微前端架构具备以下几个核心价值:
- 技术栈无关:主框架不限制接入应用的技术栈,微应用具备完全自主权
- 独立开发、独立部署:微应用仓库独立,前后端可独立开发,部署完成后主框架自动完成同步更新
- 增量升级:在面对各种复杂场景时,我们通常很难对一个已经存在的系统做全量的技术栈升级或重构,而微前端是一种非常好的实施渐进式重构的手段和策略
- 独立运行时:每个微应用之间状态隔离,运行时状态不共享
在一个系统内,微前端是应用间的架构方案。在多个应用之间,微前端则是一种系统间的架构方案。实现形式:
- 单实例:即同一时刻,只有一个子应用被展示,子应用具备一个完整的应用生命周期。
- 多实例:通常基于URL的变化来做子应用的切换,同一时刻可展示多个子应用。通常使用
Web Components
方案来做子应用封装,子应用更像是一个业务组件而不是应用。
微前端方案种类
- 中心基座模式:通过搭建基座、配置中心来管理子应用。如:Single-spa 框架、基于 single-spa 的 qiankun、iframe。
- 去中心模式:脱离基座模式,每个应用之间都可以彼此分享资源。如:
Web Components
、基于 Webpack 5 的Module Federation(模块联邦)
实现的 EMP 微前端方案(可以实现多个应用彼此共享资源分享)。 - 自组织模式:通过约定进行互调。如:利用
Nginx
路由分发实现、微件化。
微前端实现方式
iframe
每个微应用独立开发部署,通过 iframe的方式将这些应用嵌入到父应用系统中。
- 技术栈:无限制
- 优点
- 技术栈无关,子应用独立构建部署
- 实现简单,子应用之间自带沙箱,天然隔离,互不影响
- 缺点:体验差、路由无法记忆、页面适配困难、无法监控、依赖无法复用,兼容性等都具有局限性,资源开销巨大,通信困难
- 单独构建 / 部署:支持
- 构建速度:正常
- SPA(单页应用) 体验:不支持
- 项目侵入性:高
- 通信难度:高
通用中心路由基座式
微应用可以使用不同技术栈;微应用之间完全独立,互不依赖。统一由基座工程进行管理,按照DOM节点的注册、挂载、卸载来完成。
- 技术栈:无限制
- 优点:子应用独立构建,用户体验好,可控性强,适应快速迭代
- 缺点:学习与实现的成本比较高,需要额外处理依赖复用
- 单独构建 / 部署:支持
- 构建速度:正常
- SPA(单页应用) 体验:支持
- 项目侵入性:高
- 通信难度:正常
特定中心路由基座式
微应用业务线之间使用相同技术栈;基座工程和微应用可以单独开发单独部署;微应用有能力复用基座工程的公共基建。
- 技术栈:统一技术栈
- 优点:子应用独立构建,用户体验好,可控性强,适应快速迭代
- 缺点:学习与实现的成本比较高,需要额外处理依赖复用
- 单独构建 / 部署:支持
- 构建速度:正常
- SPA(单页应用) 体验:支持
- 项目侵入性:高
- 通信难度:正常
npm 集成
将微应用抽离成包的方式,发布 npm 中,由父应用依赖的方式使用,构建时候集成进项目中。
- 技术栈:无限制
- 优点:
- 编译阶段的应用,在项目运行阶段无需加载,体验流畅
- 开发与接入成本低,容易理解
- 缺点:
- 影响主应用编译速度和打包后的体积
- 不支持动态下发,npm 包更新后,需要重新更新包,主应用需要重新发布部署
- 单独构建 / 部署:不支持
- 构建速度:慢
- SPA(单页应用) 体验:支持
- 项目侵入性:高
- 通信难度:正常
webpack5 模块联邦
webpack5 模块联邦 去中心模式、脱离基座模式。每个应用是单独部署在各自的服务器,每个应用都可以引用其他应用,也能被其他应用所引用
- 技术栈:统一技术栈
- 优点:基于webpack5,无需引入新框架,学习成本低,像引入第三方库一样方便,各个应用的资源都可以相互共享应用间松耦合,各应用平行的关系
- 缺点:需要升级Webpack5技术栈必须保持一致改造旧项目难度大
- 单独构建 / 部署:支持
- 构建速度:正常
- SPA(单页应用) 体验:支持
- 项目侵入性:低
- 通信难度:正常
Web Component
Web Components
是一套不同的技术,允许创建可重用的定制元素(它们的功能封装在代码之外)并且在web应用中使用。
主要有三项主要技术组成,可以一起使用来创建封装功能的定制元素,可以在任何地方重用,不必担心代码冲突:
Custom elements(自定义元素)
:一组 JavaScript API,允许定义 custom elements 及其行为,然后可以在用户界面中按照需要使用它们。- 支持
Shadow DOM(影子DOM)
:一组 JavaScript API,用于将封装的 “影子”DOM树 附加到元素(与主文档DOM分开呈现)并控制其关联的功能。通过这种方式,可以保持元素的功能私有,这样它们就可以被脚本化和样式化,而不用担心与文档的其他部分发生冲突。 - 支持
HTML templates(HTML模板)
:<template>
和<slot>
元可以编写不在呈现页面中显示的标记模板。然后它们可以作为自定义元素结构的基础被多次重用。
使用 Web Components
实现微前端的缺点:
- 需要重写当前项目
- 生态系统不完善,技术过新容易出现兼容性问题
- 整体架构设计复杂,组件与组件之间拆分过细时,容易造成通讯和控制繁琐
Nginx 路由转发
通过 Nginx 配置实现不同路径映射到不同应用。该方式只是路由层面看起来是一个项目,实际上是通过跳转连接了多个项目。
- 技术栈:无限制
- 优点:简单、快速、易配置
- 缺点:在切换应用时触发发页面刷新,通信不易
- 单独构建 / 部署:支持
- 构建速度:正常
- SPA(单页应用) 体验:不支持
- 项目侵入性:正常
- 通信难度:高
微件化
微件(widget),指的是一段可以直接嵌入在应用上运行的代码,它由开发人员预先编译好,在加载时不需要再做任何修改或者编译。
- 打包出可以直接嵌入在页面上运行的代码,可能是一段 js,使用时直接引入即可。
- 需要实现一套微件管理机制,成本太高。
微应用化
微应用化,即在开发时,应用都是以单一、微小应用的形式存在,而在运行时,则通过构建系统合并这些应用,组合成一个新的应用。
- 通过软件工程的方式,在部署构建环境中,通过 webpack 打包,组合多个独立应用成一个单体应用。
- 需要将多个项目打包成一个,所以技术栈需要保持统一。
微应用(子应用)拆分规则
- 按照业务拆分:独立出每个业务项目,可以让整个项目架构清晰。如:电商后台,包括商品管理、商家管理、物流管理等。
- 按照权限拆分:独立出不同的权限项目,可以突出每个项目的使用范围。如:运营后台,管理员和普通运营看到的页面不一样。
- 按照变更频率拆分:独立出变更频繁的项目,可以避免频繁更新可能导致的整体项目挂掉的风险;独立出很少改动的项目,可在核心项目上投入更多精力。如:项目中,包含很少改动祖传项目和经常改动的业务项目。
- 按照组织结构拆分:独立出不同团队的项目,可以避免开发冲突,部署冲突等问题。如:一个功能复杂的项目后台,由多个团队共同开发而成。
- 跟随后端微服务拆分:有利于前后端保持统一。如:后端已经做了不同模块的微服务划分,前端按照对应划分进行拆分应用。