微前端的WWH

113 阅读6分钟

前言

微前端不是银弹,跟微服务一样接受和带来各种各样的挑战,有其优势也有其劣势,具体的使用需要结合具体的场景。就目前而言,设计出一个微服务应用并不是一件简单的事情。

What(到底什么是微前端)?

“ 微前端 ”一词最早于2016年底在ThoughtWorks Technology Radar中提出。它将微服务的概念扩展到前端世界。当下的趋势是打造一个颇具特色且功能强大的浏览器应用程序(又名单页应用程序),该应用程序位于微服务架构之上。随着时间的流逝,通常由独立团队开发的前端层会不断增长,并且变得更加难以维护。这就是我们所说的 Frontend Monolith(前端巨石)。

简单来说,微前端其实就是将微服务的架构思想引入到前端的层面并应用于浏览器端,对于微服务的解释这里引入一段话。

微服务体系结构风格是一种将单个应用程序开发为一组小型服务的方法,每个服务在其自己的进程中运行,并与轻量级机制(通常是HTTP资源API)通信。这些服务是围绕业务能力构建的,可通过完全自动化的部署机制独立部署。这些服务的集中管理是最低限度的,可以用不同的编程语言编写,并使用不同的数据存储技术。
---- Martin Fowler的博客 martinfowler.com/microservic…

简单来说就是将一个Web应用拆分成多个小的子Web应用,每个子Web应用都服务于整体的同时又具有单独开发、单独运行、单独构建部署的能力,而实现这个能力的就是微前端。

Why(为什么要使用微前端)?

首先我们需要明确一下使用微前端能达到什么样的效果,这样其实也就能反推出为什么要使用微前端:

  1. 抹平技术栈差异,所有应用都可以平滑接入
  2. 每个应用单独开发,可以更加轻易的升级所有依赖包
  3. 将大型应用拆分为更细粒度,避免整体项目过于庞大成为巨石应用
  4. 每个子应用更易维护,同时新应用没有历史包袱开发过程更舒服,可以与时俱进不断引入新的框架和技术
  5. 每个子应用都可以由单独团队进行维护,有利于组织架构
  6. 可以使团队单独自主部署,实现Web前端的持续交付 根据以上几点不难看出,微前端更多面向的是中大型中后台应用,因为中大型中后台应用的寿命一般很长动辄3年以上,最后演变成一个巨石应用的概率往往高于其他类型的 web 应用,导致更迫切的有以上几种诉求。

How(如何编写和使用微前端)?

先来聊聊如何编写微前端,编写微前端需要克服很多困难,例如以下几点:

  1. 各子应用间的样式隔离
  2. 各子应用间的状态隔离、js运行沙箱
  3. 抹平技术栈差异,让所有应用可以平滑接入
  4. 操作复杂性
  5. 每个团队都有自己的技术选择,浏览器可能需要下载很多资源文件和重复代码
  6. 查找应用机制的实现
  7. 应用的生命周期管理
  8. 注册应用和标记应用

微前端从0到1

  1. Factory
    Factory主要提供抹平技术栈差异的能力,任何技术栈编写出来的应用经过Factory的改造都可以直接被主体应用所加载,做到框架无关,技术栈无关

  2. Register
    Register主要提供将子应用注册进主应用的能力

  3. Event bus Event bus主要用来管理主应用与子应用之间的通信,以及子应用生命周期的管理

  4. Router Router负责管理子应用的命中规则

  5. Loader 当子应用的命中规则命中后由Loader对子应用进行加载

  6. Sandbox Sandbox主要提供能将各个子应用的运行环境隔离的沙箱,避免各个子应用互相之间状态、逻辑污染

Q&A及微前端的潜在问题:

  1. 业务组件与微前端的区别是什么?

答:抽离出业务组件,其实也能在很大程度些解决一些我们之所以使用微前端所遇到的问题。但是我觉得两者最大的差异点在于,业务组件是无法抹平技术栈差异的。试想一下有一个业务团队提供了一个很棒的业务组件,也可以嵌入到我们的业务中,但是他的技术栈是vue而我们团队的技术栈是react,这将是一个多么糟糕的体验。所以我觉得二者最大的区别就是是否支持抹平技术栈差异。

  1. 为什么不直接使用iframe?

答:这其实是一个老生常谈的话题了,诚然 iframe 天然实现了浏览器端的各应用间的隔离(样式、js、状态),但iframe仍有以下几种问题:

  1. url 不同步。浏览器刷新 iframe url 状态丢失、后退前进按钮无法使用。
  2. UI 不同步,DOM 结构不共享。想象一下屏幕右下角 1/4 的 iframe 里来一个带遮罩层的弹框,同时我们要求这个弹框要浏览器居中显示,还要浏览器 resize 时自动居中...
  3. 全局上下文完全隔离,内存变量不共享。iframe 内外系统的通信、数据同步等需求,主应用的 cookie 要透传到根域名都不同的子应用中实现免登效果。
  4. 慢!每次子应用进入都是一次浏览器上下文重建、资源重新加载的过程。 其中有的问题比较好解决(问题1),有的问题我们可以睁一只眼闭一只眼(问题4),但有的问题我们则很难解决(问题3)甚至无法解决(问题2),而这些无法解决的问题恰恰又会给产品带来非常严重的体验问题,若果忽略iframe的样式问题的话,它几乎是最完美的微前端解决方案了。
  1. 技术栈一旦多样化,也意味着技术栈的混乱

  2. 应用拆分的粒度越小,也就意味着架构变得复杂、维护成本变高

  3. 应用的拆分依赖于基础设施的建设,如果大量应用依赖于基础设施,那维护基础设施也是一大挑战

  4. 开发者在调试的时候可能需要运行多个应用,来测试系统的完整流程,用整个系统的复杂度换取单个应用的简洁

参考资料: