【得物技术】前端微服务
简介
什么是前端微服务
“ 微前端 ”一词最早于 2016 年底在 ThoughtWorks Technology Radar 中提出。它将微服务的概念扩展到前端世界。当前的趋势是构建一个功能强大且功能强大的浏览器应用程序(又名单页应用程序),该应用程序位于微服务架构之上。随着时间的流逝,通常由独立团队开发的前端层会不断增长,并且变得更加难以维护。这就是我们所说的 Frontend Monolith(巨石前端)。
Micro Frontends 背后的想法是将网站或 Web 应用程序视为由独立团队拥有的功能的组合。每个团队都有自己关心和专长的不同业务或任务领域。一个团队具有跨职能,并且从数据库到用户界面,端到端地开发其功能。
但是,这个想法并不新鲜。它与“ 独立系统”概念有很多共同点。在过去,类似的方法被称为“ 垂直系统的前端集成”。但是 Micro Frontends 显然是一个更友好,更轻巧的术语。(引用资料 3)
Monolithic Frontend(巨石前端)*
Organisation in Verticals (垂直组织)*
适用场景
一般来说,有以下需求的项目可以考虑使用微服务:
维护时间长
维护人员多
祖传代码迁移平滑
在老项目中使用新技术
前两点描述的是项目的不可维护性,后两点描述的是技术的迁移升级成本。
那么,典型的场景,就是各大公司企业级的 ToB 项目了。
优点/价值
技术栈无关主框架不限制接入应用的技术栈,子应用具备完全自主权。
独立开发、独立部署子应用仓库独立,前后端可独立开发,部署完成后主框架自动完成同步更新。
增量升级在面对各种复杂场景时,我们通常很难对一个已经存在的系统做全量的技术栈升级或重构,而微前端是一种非常好的实施渐进式重构的手段和策略。
独立运行时每个子应用之间状态隔离,运行时状态不共享。
• 简单、解耦的代码库打包、热更新都会加速。
采用微服务的架构,最重要的一点,是解决遗留系统,在不需要重写原有项目的基础下,可以使用新的技术。
功能设计
微服务只是一个笼统的名称,一个被称为微服务的架构大致需要考虑以下功能,根据需求来选择不同的功能集合,再考虑实现。
实现微前端的方式
使用 HTTP 服务器的路由来重定向多个应用
在不同的框架之上设计通讯、加载机制
通过组合多个独立应用、组件来构建一个单体应用
iFrame。使用 iFrame 及自定义消息传递机制
使用纯 Web Components 构建应用
结合 Web Components 构建
图中的 o 表示支持,空白表示不支持,-表示不受影响。
可用框架参考
缺点
传输内容变大重复的公共依赖,会导致最终文件体积变大。
环境差异当开发环境和生产环境差异较大时,可能会导致问题,尤其是容器本身和其他微服务中的全局样式。
运维和管理复杂性前端将会需要管理更多的仓库、工具、构建部署、更多的域。
业务价值
如果微前端只存在工程上的价值是不值得大张旗鼓去做的。 -- 张克军
产品的组合能力
widget 的产品输出能力
具体的业务价值,视领域不同,可大可小。典型场景是云平台,期望是对不同用户提供产品的不同组合,那么微服务的提供的平台、产品的被集成能力就非常契合。
各厂分析实现
前言
由于前端微服务兴起并不久,市面上并没有统一的做法,实现效果、实现方式千差万别。就拿“是否支持不同技术栈”来说,阿里的 qiankun 视之为微服务的核心价值,而 爱奇艺 和 ThoughtWorks 的 mooa 实现中就没有考虑支持不同技术。
为了能更加清楚得分析使用场景和各中利弊,特别建立本文档,记录下各个实现的重点内容。
爱奇艺技术产品团队
目标
框架与业务更加的解耦
模块的独立部署、发布等提高迭代效率
效果
🔲 独立开发:需要奖容器和全部微服务一起启动
✅ 独立部署
🔲 独立技术栈:仅支持 vue
🔲 tree shake:手动将 Vue,Router,store,RenderPage 写到全局资源,通用模块注册为懒加载组件
✅ 环境隔离:
🔲 多个应用同时运行:同时只能运行一个
🔲 公用依赖:否
🔲 依赖冲突:否
🔲 集成编译:未知
实现/特点
应用资源:每个应用自己打包生成 manifest,标注资源地址
路由:统一使用全局路由,子模块的路由加载时合并入全局路由
渲染页面:document.head 中插入 script,再主动调用 window.mp.render_home(‘#containerId’)来渲染页面
只支持同一版本的 vue,定制化程度非常高的方案,优点是相对简单,缺点是用处不大。
美团 用微前端的方式搭建单页应用
目标
合并多个业务成一个
效果
🔲 独立开发:需要奖容器和全部微服务一起启动
✅ 独立部署
🔲 独立技术栈
🔲 tree shake
✅ 环境隔离
🔲 多个应用同时运行:同时只能运行一个
🔲 公用依赖:否
🔲 依赖冲突:否
🔲 集成编译:未知
实现/特点
容器提供了额外的功能 * 用户登录机制 * 菜单权限获取 * 全局异常处理 * 全局数据打点
路由由三部分组成权限菜单树、导航和路由树
阿里 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 劫持 windowunmount 生命周期时恢复 window 属性和被劫持的方法
prefetch 预加载 requestIdleCallback 时机请求所有注册的 app,匹配 style 和 script 资源,预先下载缓存
接入
添加 package.json 的 name 属性,作为唯一标记,应用之间不重复
打包出来的配置需要更改
需要提供一个不带侧边栏(头)的版本
生命周期(简易)
后续
随着技术的更新发展,目前有越来越多的微前端方案出现了,例如基于 webpack5 联邦模块实现的EMP,允从独立组件组建和管理前端的 Bit,新的框架带来新的创意,让我们拭目以待!
引用
采用前端微服务架构 - luca mezzalira
微前端的那些事儿 - 知乎 ID: phodal
微前端 - Michael Geers
微前端 - Cam Jackson
可能是你见过最完善的微前端解决方案 - 知乎 ID: kuitos
微前端的核心价值 - 知乎 ID: kuitos
文|巧克力
关注得物技术,携手走向技术的云端
版权声明: 本文为 InfoQ 作者【得物技术】的原创文章。
原文链接:【http://xie.infoq.cn/article/6a5cedc79b09cbcd870bd9db6】。
本文遵守【CC-BY 4.0】协议,转载请保留原文出处及本版权声明。
评论 (2 条评论)