【得物技术】前端微服务

731 阅读7分钟

简介

什么是前端微服务

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

Micro Frontends背后的想法是将网站或Web应用程序视为由独立团队拥有的功能的组合。每个团队都有自己关心和专长的不同业务或任务领域。一个团队具有跨职能,并且从数据库到用户界面,端到端地开发其功能。

但是,这个想法并不新鲜。它与“ 独立系统”概念有很多共同点。在过去,类似的方法被称为“ 垂直系统的前端集成”。但是Micro Frontends显然是一个更友好,更轻巧的术语。(引用资料3)

Monolithic Frontend(巨石前端)* 1582646032946-f7b154e3-5792-43de-80c4-e58ee3046516.png Organisation in Verticals (垂直组织)* 1582646057528-24dc0893-3334-4201-907e-b4d0896dbc66.png

适用场景

一般来说,有以下需求的项目可以考虑使用微服务:

  • 维护时间长
  • 维护人员多
  • 祖传代码迁移平滑
  • 在老项目中使用新技术

前两点描述的是项目的不可维护性,后两点描述的是技术的迁移升级成本。

那么,典型的场景,就是各大公司企业级的ToB项目了。

优点/价值

  • 技术栈无关
    • 主框架不限制接入应用的技术栈,子应用具备完全自主权。
  • 独立开发、独立部署
    • 子应用仓库独立,前后端可独立开发,部署完成后主框架自动完成同步更新。
  • 增量升级
    • 在面对各种复杂场景时,我们通常很难对一个已经存在的系统做全量的技术栈升级或重构,而微前端是一种非常好的实施渐进式重构的手段和策略。
  • 独立运行时
    • 每个子应用之间状态隔离,运行时状态不共享。
  • • 简单、解耦的代码库
    • 打包、热更新都会加速。

采用微服务的架构,最重要的一点,是解决遗留系统,在不需要重写原有项目的基础下,可以使用新的技术。

功能设计

微服务只是一个笼统的名称,一个被称为微服务的架构大致需要考虑以下功能,根据需求来选择不同的功能集合,再考虑实现。 1582660194107-f1c3e2d7-1dc9-471d-bcfc-ddca19d98702.png

实现微前端的方式

  • 使用 HTTP 服务器的路由来重定向多个应用
  • 在不同的框架之上设计通讯、加载机制
  • 通过组合多个独立应用、组件来构建一个单体应用
  • iFrame。使用 iFrame 及自定义消息传递机制
  • 使用纯 Web Components 构建应用
  • 结合 Web Components 构建 1582664777517-339d4395-9ec1-477e-9682-59cee63cf573.png

可用框架参考

Qiankun

Single-SPA

缺点

  • 传输内容变大
    • 重复的公共依赖,会导致最终文件体积变大。
  • 环境差异
    • 当开发环境和生产环境差异较大时,可能会导致问题,尤其是容器本身和其他微服务中的全局样式。
  • 运维和管理复杂性
    • 前端将会需要管理更多的仓库、工具、构建部署、更多的域。

业务价值

如果微前端只存在工程上的价值是不值得大张旗鼓去做的。 -- 张克军

  • 产品的组合能力
  • widget 的产品输出能力

具体的业务价值,视领域不同,可大可小。典型场景是云平台,期望是对不同用户提供产品的不同组合,那么微服务的提供的平台、产品的被集成能力就非常契合。

各厂分析实现

前言

由于前端微服务兴起并不久,市面上并没有统一的做法,实现效果、实现方式千差万别。就拿“是否支持不同技术栈”来说,阿里的 qiankun 视之为微服务的核心价值,而 爱奇艺 和 ThoughtWorks 的 mooa 实现中就没有考虑支持不同技术。

为了能更加清楚得分析使用场景和各中利弊,特别建立本文档,记录下各个实现的重点内容。

爱奇艺技术产品团队

目标

  • 框架与业务更加的解耦
  • 模块的独立部署、发布等提高迭代效率

效果

🔲 独立开发:需要奖容器和全部微服务一起启动

✅ 独立部署

🔲 独立技术栈:仅支持 vue

🔲 tree shake:手动将 Vue,Router,store,RenderPage 写到全局资源,通用模块注册为懒加载组件

✅ 环境隔离:

🔲 多个应用同时运行:同时只能运行一个

🔲 公用依赖:否

🔲 依赖冲突:否

🔲 集成编译:未知

实现/特点

  • 应用资源:每个应用自己打包生成 manifest,标注资源地址
  • 路由:统一使用全局路由,子模块的路由加载时合并入全局路由
  • 渲染页面:document.head 中插入 script,再主动调用window.mp.render_home(‘#containerId’)来渲染页面

只支持同一版本的vue,定制化程度非常高的方案,优点是相对简单,缺点是用处不大。

美团 用微前端的方式搭建单页应用

目标

合并多个业务成一个

效果

🔲 独立开发:需要奖容器和全部微服务一起启动

✅ 独立部署

🔲 独立技术栈

🔲 tree shake

✅ 环境隔离

🔲 多个应用同时运行:同时只能运行一个

🔲 公用依赖:否

🔲 依赖冲突:否

🔲 集成编译:未知

实现/特点

  • 容器提供了额外的功能 * 用户登录机制 * 菜单权限获取 * 全局异常处理 * 全局数据打点
  • 路由由三部分组成权限菜单树、导航和路由树

美团 大规模微服务通信框架及治理体系OCTO核心组件开源

阿里 qiankun开源方案

目标

  • 简单,像接入 iframe 一样容易
  • 解耦,技术栈无关

效果

✅ 独立开发:容器和业务无耦合,可以随意启动

✅ 独立部署

✅ 独立技术栈

🔲 tree shake:无

✅ 环境隔离:可选沙盒模式

✅ 多个应用同时运行:可选支持模式

🔲 公用依赖:否

🔲 依赖冲突:否

🔲 集成编译:否

实现/特点

  • 实现基于 single-spa
  • HTML Entry 接入方式:接入子应用像iframe一样简单
    • 只配置子应用的首页地址(m.poizon.com)
    • 根据地址来请求整个页面,从页面中提出 script 和 style 资源
    • script 通过 eval 来执行
  • 资源预加载
    • 配合 HTML Entry ,在空闲时候加载子应用的首页的 style 和 script, style 写入 html,script 放入缓存
  • 样式隔离:子应用之间的样式互不干扰
  • JS 沙箱:子应用之间的 全局变量/事件 不冲突
    • mount 生命周期时 proxy 劫持 window
    • unmount 生命周期时恢复 window 属性和被劫持的方法
  • prefetch 预加载
    • requestIdleCallback 时机
    • 请求所有注册的app,匹配 style 和 script 资源,预先下载缓存

接入

  • 添加 package.json 的 name 属性,作为唯一标记,应用之间不重复
  • 打包出来的配置需要更改
  • 需要提供一个不带侧边栏(头)的版本

生命周期(简易) 1583242385926-d81003ec-c0bb-45a1-b27d-d484c28fff6d.png

后续

随着技术的更新发展,目前有越来越多的微前端方案出现了,例如基于 webpack5 联邦模块实现的EMP,允从独立组件组建和管理前端的 Bit,新的框架带来新的创意,让我们拭目以待!

引用

  1. 采用前端微服务架构 - luca mezzalira
  2. 微前端的那些事儿 - 知乎ID: phodal
  3. 微前端 - Michael Geers
  4. 微前端 - Cam Jackson
  5. 可能是你见过最完善的微前端解决方案 - 知乎ID: kuitos
  6. 微前端的核心价值 - 知乎ID: kuitos

文|巧克力

关注得物技术,携手走向技术的云端