一、业务背景目前客服一站式工作台包括在线服务、电话、工单和工具4.大功能,页面基本结构如下:各业务模块相对独立,各有独立的业务系统,单个模块规模比较大,项目整体采用SPA+iframe的架构模式,工单系统通过iframe嵌套。在客服业务不断迭代的过程中,SPA+iframe的架构模式暴露出了很多问题。主要问题如下:问题一:在SPA架构模型中,由于每个模块都集中在一个架构中,导致首屏加载资源过多。首屏加载速度慢;SPA只有一个入口文件,因此需要兼容各个模块的业务模型,导致入口文件代码中有很多条件语句,代码混乱,线上出现问题时很难排查.如果有新同学参与开发和业务梳理也比较困难,有时甚至难以理解。问题二:项目中嵌套了大量的iframe,iframe也会拖慢页面的加载速度。当iframe使用postMessage通信时,也会造成数据延迟、数据丢失等各种问题。当长时间使用客服,当切换iframe时,上一页中的页面无法完全释放时,浏览器占用的内存会不断飙升,最终导致浏览器崩溃。基于以上两个问题,我们采用微前端技术对一站式工作台的业务进行拆分。本文主要阐述拆分过程中遇到的问题和挑战。2.技术方案研究通过对微前端技术方案的研究,我们可以知道,微前端是一种类似于微服务的架构。本体应用改造为将多个小前端应用聚合为一个的应用,具有以下核心价值:技术栈无关:主框架不限制接入应用的技术栈,微应用有完全自主和独立开发、独立部署:应用仓库独立,前后端可独立开发。部署完成后,主框架自动完成同步更新和增量升级:当面对各种复杂的场景时,我们通常很难升级或重装现有系统的整个技术栈。微前端是一个很好的实现渐进式重构的手段和策略。独立运行时:各个微应用之间状态隔离,运行时状态不共享。通过对开源社区相关微前端技术的研究,目前主流的微前端解决方案主要有以下几种:技术框架:iframe、single-spa、qiankun、icestark、Garfish、microApp、ESM、EMP技术亮点:js入门,html入口,沙盒隔离,风格隔离,webComponent,ESM、ModuleFederation#####解决方案#####来源#####特点#####缺点iframe-自然隔离风格和脚本,多页面窗口大小不易控制,隔离无法打破,导致应用之间的上下文无法共享,带来开发体验和产品体验等问题。无法实现单页,很多功能在主应用中无法正常显示。single-spa国外JsEntry,主应用重写window.addEventListener拦截监听Routing时间,执行内部reroute逻辑,根据reroute加载子应用,不适合需要缓存加载多个应用的??场景需要核心功能在umd模式下编译。对于AMD,systemJs支持并不友好,官方也没有支持vite搭建icestark。阿里通过缓存将大部分配置写入window['icestark']中。全局变量只支持React,不支持跨框架。FriendlyGarfishbyte是现有MFE框架的增强版,VMsandbox-microApp京东基于webComponent实现存在兼容性问题,对微前端的探索还不够成熟ESM-micro-module,通过构建工具编译为js,远程加载模块,无技术栈限制,与页面路由无关,可任意挂载。不是兼容所有浏览器(可以通过编译工具解决),样式需要手动隔离(可以通过css模块解决)。应用程序通信不友好。EMP团聚时代基于ModuleFederation、去中心化、跨应用状态共享、跨框架组件调用、远程拉取ts声明文件、微应用动态更新、第三方依赖共享等目前无法实现的能力涵盖所有框架流程。研究并结合我们的业务现状,我们采用了qiankun+ModuleFederation作为我们微前端的技术框架,将应用按照功能拆分成4个独立的系统,可以独立开发部署,可以根据需要访问到权限配置。进入基地;其中项目涉及依赖其他模块,远程组件用于加载依赖组件,例如:IM,手机会依赖工单创建、补偿、工单明细、订单明细等工单、工具中的组件。box目前依赖IM中的sessionrecording组件,所以IM和工单可以作为远程终端,IM、phone、toolbox可以作为host端,提供更友好的组件复用方式,取消之前的iframe加载方式,并且也不需要使用qiankun加载多个微应用来实现,避免了重复加载大量资源,提高了页面的响应速度1.一站式workbench微前端架构图2.MF远程组件规划图我们通过研究结合实际项目,采用了qiankun作为业务应用拆分的微前端框架,模块联邦作为该框架用于在不同的应用程序之间共享远程组件,形成一个初步的框架体系。在这个框架体系下,我们面临着很多问题。技术挑战如下:微应用需要具备缓存(keep-alive)能力,应用切换状态不能丢失。需要同时加载多个微应用。沙盒隔离及第三方资源引入base-micro-application,micro-application-micro应用之间如何通信如何访问远程组件式隔离库-微应用连接图1.Qiankun提供的微应用缓存能力的实现我们有两种注册方法:registerMicroApps,loadMicroAppregisterMicroApps(apps,lifeCycles?):适用于基于路由的场景,路由变化会帮我们自动注册微应用,并销毁上一个微应用。对于不需要缓存的应用,推荐使用这种方式。简单易用,只需要为小程序设置独立的路由即可。只要符合规则。以下是乾坤官网的demo示例:import{registerMicroApps}from'qiankun';registerMicroApps([{name:'app1',entry:'//localhost:8080',container:'#container',activeRule:'/react',props:{name:'kuitos',},},{name:'app2',entry:'//localhost:8081',container:'#container',activeRule:'/vue',props:{name:'Tom',},},]],{beforeLoad:(app)=>console.log('beforeload',app.name),beforeMount:[(app)=>console.log('beforemount',app.name)],},);loadMicroApp(app,configuration?):适用于需要手动加载/卸载微应用的场景。对于我们来说,需要实现缓存,同时加载多个微应用,这种方式比较合适。结论:在qiankun2.0之后,官方为我们提供了loadMicroAppAPI,为我们带来了手动控制应用加载/卸载的能力,而且不是基于routeBase来加载资源,不用担心关于切换菜单卸载时上一个微应用处于活动状态。基于loadMicroApp手动控制微应用加载的特性,如果要实现保活能力,可以在base和微应用上设置合适的保活缓存策略,然后使用"display:none”来控制开关的显示和隐藏(DOM重新渲染会导致历史状态丢失),为dock中的每个微应用设置一个挂载点,之前的微应用DOM不会被挂载切换应用程序时卸载。基座逻辑:当我们检测到路由变化时,我们手动调用loadMicroAppFn来加载相应的微应用程序。对于需要同时加载多个的场景,我们可以循环调用load(vite构建下加载多个微应用可能会失败,推荐使用webpack构建)。具体原因请参考issue:请问以后是否考虑支持vite·Issue#1257·umijs/qiankun[[求问题]主应用和子应用都用vite,用loadMicroApp加载同时加载多个子应用#1861](https://github.com/umijs/qian...)//手动加载微应用方法封装constloadMicroAppFn=(microApp)=>{constapp=loadMicroApp({...microApp,props:{...microApp.props,//发送到微应用的数据microFn:(status)=>setMicroStatus(status)},},{sandbox:true,singular:false});returnapp;}//为每个微应用节点提供一个挂载的容器:
