首页>国内 > 正文

基于微前端的业务逻辑拆分

2023-03-10 12:10:57来源:移动Labs

一、什么是微前端?

微前端是一种多个团队通过独立发布功能的方式来共同构建现代化 web 应用的技术手段及方法策略。

微前端在2016年ThoughtWorks Technology Radar正式被提出。借鉴了微服务的架构理念,将一个庞大的前端应用拆分为多个独立灵活的小型应用,每个应用都可以独立开发、独立运行、独立部署,再将这些小型应用联合为一个完整的应用。微前端既可以将多个项目融合为一,又可以减少项目之间的耦合,提升项目扩展性,相比一整块的前端仓库,微前端架构下的前端仓库倾向于更小更灵活。


(资料图)

架构特点

技术栈无关:主框架不限制接入应用的技术栈,子应用可自主选择技术栈;独立开发/部署:各个团队之间仓库独立,单独部署,互不依赖;增量升级:当一个应用庞大之后,技术升级或重构相当麻烦,而微应用具备渐进式升级的特性;独立运行时:微应用之间运行时互不依赖,有独立的状态管理;提升效率:应用越庞大,越难以维护,协作效率越低下。微应用可以很好拆分,提升效率。

二、目前可用的微前端方案2.1 基于iframe完全隔离

作为前端开发,我们对iframe已经非常熟悉了,在一个应用中可以独立运行另一个应用。

优点:

非常简单,无需任何改造;完美隔离,JS、CSS都是独立的运行环境;不限制使用,页面上可以放多个iframe来组合业务。

缺点:

无法保持路由状态,刷新后路由状态就丢失;完全的隔离导致与子应用的交互变得极其困难,只能采用postMessage方式;iframe中的弹窗无法突破其本身;整个应用全量资源加载,加载太慢。2.2 基于single-spa路由劫持

single-spa (opens new window)是一个目前主流的微前端采用基座技术方案,其主要实现思路:预先注册子应用,监听路由的变化,匹配到激活的路由则加载子应用资源,顺序调用生命周期函数(初始化,挂载,卸载)并最终渲染到容器。

优点:

有开箱即用的API;技术栈无关,任意技术栈均可接入;HTML Entry接入方式,将整个微应用打包成一个JS文件,发布静态资源服务器,然后在主应用中配置该JS文件的地址告诉single-spa去这个地址加载微应用。

缺点:

对微应用侵入性强,会将应用打包为一个JS文件,常用的优化措施,如按需加载,css独立打包等都没有了;没有做样式隔离,样式容易混淆覆盖;没有做JS隔离,JS全局对象污染;无预加载机制,加载资源太慢;微应用之间没有任何通信手段,只能用户自己实现。2.3 基于web components封装组件

官方提出的组件化方案,它通过对组件进行更高程度的封装,以组件加载的方式将微应用整合在一起实现应用之间的解耦。

优点:

加载子应用比single-spa注册监听方式更加优雅;技术栈无关,是浏览器原生组件,在任何框架中都可以使用;无需与其他应用之间产生任何关联;应用间采用shadow dom,隔离样式。

缺点:

浏览器兼容性不好。2.4 quankun

Quankun是对single-spa做了一层封装,主要解决了single-spa的痛点和不足,通过import-html-entry包解析HTML获取资源路径,然后对资源进行解析,加载。

优点:

阿里团队开发维护,文档多,有开箱即用的API;JS沙箱机制,确保应用直接变量事件不冲突;资源预加载,在浏览器空闲时间预加载未打开的微应用资源,加速了微应用的打开速度;可用于任意JS框架,像嵌入一个iframe,且兼容IE11。

缺点:

上线部署文档少;只能解决子项目之间的样式相互污染,不能解决子项目的样式污染主项目的样式。2.5 EMP

主要基于Webpack5 Module Federation,是一种去中心化的微前端实现方案,不仅能很好的隔离应用,还可以轻松实现应用之间的资源共享和通信。

优点:

快速封装可复用模块,无需单独拆包发布到NPM,可直接暴露需要共享的模块;实时动态更新,只需要发布基站应用,只需要访问时刷新,即可使用最新业务模块;引入端无需手动更新,远端模块灵活维护和引入端可以自由组合,甚至可以运行是引入使用远端模块;做到第三方依赖共享,使代码尽可能地重复利用,减少加载内容。

缺点:

对webpack强依赖,老旧项目不友好;没有做CSS隔离和JS隔离,需要靠用户自觉;子应用保活、多应用激活无法实现;主、子应用的路由可能发生冲突。三、我们要解决的问题

拆分巨型应用,使应用方便迭代更新,提高开发部署效率

单体应用在一个相对长的时间跨度下,由于参与的人员、团队的增多、变迁,从一个普通应用演变成一个巨石应用(Frontend Monolith)后,随之而来的应用不可维护的问题。这类问题在企业级 Web 应用中尤其常见。而微前端思想可以将一个庞大的前端应用拆分为多个独立灵活的小应用,每个应用可以独立开发,独立更新,独立部署,减少模块之间的耦合性,提高项目扩展性,有利于各子应用渐进式优化,不影响新增功能以及其他子应用的运行。

跨团队协作,实现需求分工,争取资源最优化,提高工作效率

大需求需要拆分,不同的部分需要不同的业务能力,需要涉及多个团队甚至多个部门协同开发,所谓专业的团队做专业的事情,细化能力,实现能力效用最大化,提高团队整体工作效率,实现1+1>2的效果。

兼容历史应用,实现增量开发

旧项目技术栈不统一,微前端主框架可以不限制接入应用的技术栈,可以随时加载不同技术栈模块,不需要为了兼容现有项目做大规模改造重构,提升开发,测试与维护效率。

四、我们的方案

1️⃣采用基于web component的micro-app框架为基础,拆分出可独立运行的子应用;

2️⃣进一步封装业务逻辑层,实现基于js沙箱与shadow dom的代码隔离;

3️⃣抽离子应用的公用模块,进一步缩减巨石项目代码规模,提高迭代维护效率。

4.1 技术特点

高扩展性、独立性、开放性:基于micro-app实现微前端主框架,将主应用拆分为主平台系统和各子系统等可以独立交付运行的前端子应用,再进一步将业务模块抽象,公用模块从子应用中抽离,模块化开发部署,提高了各个子应用/业务模块的可拓展性,减少耦合性,提高开发效率,降低交付成本。

统一功能模块独立性,提高安全性:用户信息,角色权限等通用业务功可以抽象出来单独开发部署,降低重复开发,减少项目整理代码量,但因为需要集成到不同的子应用,为避免和宿主页面样式冲突,采用基于shadow dom+JS沙箱机制,建立独立作用域,实现custom element,将JS和CSS都被隔绝在dom作用域中,实现代码隔离,使代码更干净,整洁,降低耦合性。

抽离通用功能模块,进一步缩减项目冗余:菜单,头部,脚部,登录,注册等使用vite工具将其打包微ESM模块,对于当前单一技术栈实现的业务项目,不需要每个子应该都重新开发公用模块,让代码包总体积更小,提高开发效率,并实现模块的按需异步加载,提升页面整体加载速度。

4.2 什么是JS沙箱

JS沙箱主要是用于隔离挂载在window上的变量,保证应用之间js环境得独立。在子应用运行时访问的window其实是一个Proxy代理对象。所有子应用的全局变量变更都是在闭包中产生的,不会真正回写到window上,这样就能避免多实例之间的污染。

4.3 什么是shadow dom

Shadow-dom是游离在DOM树之外的节点树,他的创建基于自定义DOM元素(非document),并且创建后的shadow-dom节点可以从界面上直观的看到。更重要的是,shadow-dom具有良好的密封性,可以隔离css样式,避免css全局样式污染。

4.4 模块之间如何通信

该方案涉及按照业务拆分的子应用,按照功能拆分的子模块,他们的通信方式是不通的。

1.按照业务拆分的子应用并不是一个模块,而是一个可以独立运行的应用,然而应用之间的频繁的通信会增加应用的复杂度和耦合度,因此要尽量减少子应用之间的通信,非必要不交互。这里我们使用micro-app官方提供的API即可实现。

2.按照功能模块拆分的子模块,既是基于web component实现的子模块,之间的通信可遵循父组件加载子组件,父子组件之间的通信。

关键词:

相关新闻

Copyright 2015-2020   三好网  版权所有 联系邮箱:435 22 640@qq.com  备案号: 京ICP备2022022245号-21