【玩转微前端1】如何做技术选型

2022/04/07 posted in  微前端
Tags:  #微前端

当前市面上已出现了很多微前端方案,如何做出正确的选择是一件不容易的事情。

在开始介绍这些方案之前,我们有必要先了解一下微前端架构的核心原则,从而更好的去衡量微前端方案是否成熟。

核心原则

应用独立

这里说的独立包含三个方面:

  • 独立开发:每个微应用由不同业务团队开发,实现团队自治。

image-20220331172853831
image-20220331172853831

  • 独立部署:微应用可独立部署运行,每个应用可以有自己的交付部署流程,某个微应用出现故障不影响其他应用。

image-20220331173031824
image-20220331173031824

  • 独立运行:既可以组合运行,也可以单独运行,运行时环境隔离,提供JavaScript沙箱,CSS 样式隔离,避免应用间运行时污染。

消息通信

完善的通信机制,可以降低主应用和微应用、微应用和微应用之间的数据共享难度,是否有完善的通信机制是选型考量的一个关键因素。

技术栈无关

主应用不限制子应用接入的技术栈。不限制技术栈有如下好处:

  • 每个应用可以结合团队情况选择不同的技术栈,也可以集成一些采用了不同技术栈的老旧项目。
  • 应用技术栈切换升级不影响其他应用,可以实现增量升级。通常我们很难对一个已有的系统做全量的技术栈升级或重构,而微前端是一种非常好的实施渐进式重构的手段和策略。

依赖复用

解决各应用间依赖、公共逻辑需要重复维护的问题。应用间相同的依赖需要重复下载。

方案对比

接下来,我们从四大流派来看一下当下有哪些方案可以选择,并简单做个对比:

传统式

1. 路由分发(服务端)

描述: 在HTTP服务器通过反向代理将不同的路由分发到对应的应用上。

http {
  server {
    listen       80;
    server_name  www.phodal.com;
    location /api/ {
      proxy_pass http://http://172.31.25.15:8000/api;
    }
    location /web/admin {
      proxy_pass http://172.31.25.29/web/admin;
    }
    location /web/notifications {
      proxy_pass http://172.31.25.27/web/notifications;
    }
    location / {
      proxy_pass /;
    }
  }
}

优点: 简单、快速、易配置。

缺点:

  • 应用是完全分开的,通信和数据资源共享很困难;
  • 切换应用需要刷新页面,体验不好;
  • 完全是基于路由的,无法同时加载多个应用。

2. IFrame

描述: 将微应用通过iframe载入。

**优点:**接入简单,兼容性好,原生支持沙箱隔离。

缺点:

  • 隔离性无法突破,应用间上下文无法共享,比如在子应用弹窗问题(只能基于子应用可视区定位,不能基于整个页面定位)。
  • 应用间通信需要自行实现一套基于postMessage的通信机制。
  • 刷新会导致iframe Url状态丢失,iframe 和主页面共用一个浏览历史,后退前进按钮无法使用。

自组织式

3. Npm集成

描述: 将微应用抽离成包的方式,发布到Npm中,再在主应用中将这些微应用作为依赖项,构建时候集成进项目中。

优点: 开发与接入成本低,容易理解。

缺点:

  • 影响主应用编译速度和打包后的体积。
  • 不支持动态更新,npm包更新后,需要重新更新包,主应用需要重新发布部署。
  • 因为业务应用不能发布到公开库,需要自己搭建npm私有库,提高了工程难度。

4. JS集成

**描述:**每个微应用提供一个入口js,会导出一个全局变量,主应用引入该js,安装应用时调用相关函数,挂载渲染微应用。

**优点:**相比Npm集成方案,优化的地方是微应用不用构建到主应用中,而是独立构建的。

缺点: 规范、通信、沙箱都需要自己实现,依赖开发人员设计能力。

<html>
  <head>
    <title>Feed me!</title>
  </head>
  <body>
    <h1>Welcome to Feed me!</h1>

    <!-- 这些脚本不会马上渲染应用 -->
    <!-- 而是分别暴露全局变量 -->
    <script src="https://browse.example.com/bundle.js"></script>
    <script src="https://order.example.com/bundle.js"></script>
    <script src="https://profile.example.com/bundle.js"></script>

    <div id="micro-frontend-root"></div>

    <script type="text/javascript">
      // 这些全局函数是上面脚本暴露的
      const microFrontendsByRoute = {
        '/': window.renderBrowseRestaurants,
        '/order-food': window.renderOrderFood,
        '/user-profile': window.renderUserProfile,
      };
      const renderFunction = microFrontendsByRoute[window.location.pathname];

      // 渲染第一个微应用
      renderFunction('micro-frontend-root');
    </script>
  </body>
</html>

微件式

5. Web Component

**描述:**微应用导出的是一个自定义元素(Web Component),加载微应用时渲染对应的元素即可。

**优点:**浏览器自带能力,接入简单,自带Shadow DOM沙箱。

**缺点:**兼容性不太好,暂时只有较新的浏览器支持,但未来可期。

6. MicroApp

描述: [MicroApp](https://cangdu.org/micro-app/是京东零售推出的一款微前端框架,是基于WebComponent实现的一种用于构建微前端应用的极简方案。

d879637b4bb34253
d879637b4bb34253

**优点:**接入成本很低,只需一行代码即可实现微前端,提供了js沙箱样式隔离元素隔离预加载数据通信静态资源补全等一系列完善的功能。

**缺点:**依赖于CustomElements和Proxy两个较新的API,兼容性需要考虑。

7. EMP

描述: EMP由欢聚时代(YY)自主研发的单页微前端解决方案,主要基于Webpack5的新特性Module Federation实现。

**优点:**强调去中心化,每个微应用都可以引入其他的微应用,无中心应用(容器/主应用)的概念。

缺点:

  • 接入有一定成本,不同技术栈接入有一定难度;
  • 因为使用了Module Federation,所以仅支持webpack5+构建的应用。

基座式

7. Single-spa

描述:Single-spa在上面的js集成方案,加入了生命周期,算是比较老牌的微前端框架了。

**优点:**支持生命周期和代码延迟加载。

**缺点:沙箱环境需要自行处理,有一定的侵入性。

8. qiankun

描述:qiankun由蚂蚁团队基于single-spa构建的微前端解决方案,功能比较完善,已有多个成功应用案例验证,是目前应用最多的微前端框架。

v2-d55549366b52cde19c93835cfa2a58c9_1440w
v2-d55549366b52cde19c93835cfa2a58c9_1440w

优点:

  • 接入成本相对较低,框架本身已包含构建微前端系统时所需要的基本能力。
  • 微应用入口支持多种方式。

**缺点:**没有提供依赖复用,需要自行解决。

9. icestark

描述: icestark是阿里飞冰出品的面向大型系统的微前端解决方案。

**优点:**相比qiankun,支持微模块,一种粒度更小的挂件,可以随处挂载。

**缺点:**样式隔离问题目前还只能靠规范来规避,Shadow DOM方案还在实验中。

10. Garfish

描述:Garfish是字节跳动出品,包含构建微前端系统时所需要的基本能力。

image.png
image.png

**优点:**api简单,接入成本低,自带依赖共享api,支持插件扩展。

路在何方

可以看到,在上述方案中,比较成熟的方案有MicroApp、EMP、qiankun、Garfish。当下微前端相应的解决方案其实挺多的,但是并不存在银弹,每一个方案都有优缺点,只有结合实际需求进行选择最合适的那个方案就行。

当然除了前面说的几个微前端的核心原则,一般在选型时,我们还注意如下几个纬度:

纬度 描述
稳定性 该方案是否经历了社区的考验,有较多的成熟案例,同时保持较高的活跃性,有完善的文档。
可拓展性 支持定制化开发,提供较高的可拓展能力,同时成本可以在接受范围内
可控性 发生问题后,能够在第一时间内进行问题排查,以最快的响应速度来处理问题,修复的方案是否会依赖于外部环境
低成本 学习成本和项目接入改造成本是一个很重要的考量因素,成本太高会适得其反。

所以,结合上述和项目的一些因素,当时我们最终选择了qiankun。接下来我们就聊一聊qiankun。

« 【玩转微前端2】聊聊qiankun 【玩转微前端0】微前端是什么 »