TL;DR
所谓微前端(Micro-Frontend)更像是一种新的高技术栈宽容度的开发框架,它看似能解决一些异构前端整合的问题,却也没有完全解决。对于存量前端项目在接入微前端时需要非常高的适配成本。所以我认为所谓的微前端更多的是对标微服务(Microservice)一种噱头。
起因
其他项目组 A 采购了一套所谓”自主研发”的微前端框架,并基于这套框架开发了一个项目,实现业务功能之余还希望整合复杂切凌乱的内部各个系统域名不同、登录状态不通的问题。然后项目组 A 找到了我,需要接入我之前设计构建的系统。
问题
我设计的系统是标准的同域下微服务应用,前端是每个提供服务的微服务各自对应一个前端项目,公共代码使用git submodule
共享。各微服务前端业务调用自身对应的微服务后端接口,前端不跨微服务调用,如果有调用其他微服务的需求那是当前微服务的业务需要,微服务后端自身根据业务需要通过微服务后台相互调用。
这样设计一是为了防止前后端、微服务开发者之间推锅,前端出现的报错肯定是对应的后端返回,不需要再让前端排查是调用的哪个微服务;二是前端代码项目的代码更能针对对应微服务业务,前端出现问题是影响面会小很多。
在架构上使用nginx
之类的网络负载把所有前后端拉到同一个域名下,这样前、后端在编码中不需要添加任何 IP/域名的配置,前后端部署在什么位置也不需要关心,只要能拉到同一个域名下就可以。
上面的架构我认为也算一些”类微前端”的实现,每个前端项目各自维护自身业务代码,通用代码通过git submodule
共享,部署后在同域下共同使用浏览器同域下的资源(localStorage、cookies、sessionStorage 等)。各前端项目路由相当于后端微服务暴露的服务,在同域下下简单的window.replace
就可以进行跳转,传递数据可以通过 url,也可以使用共享的资源。
然而这个架构接入项目组 A 的微前端框架却遇到了巨大的困难,这不经让我思考到底什么是微服务。举两个所遇到的困难,首先我们的前后端并不跨域,所以没有任何一个服务、中间件存在处理跨域请求的配置;第二个是我们的前端使用window.replace
在各前端项目之间跳转,任意一个前端项目并没有其他前端项目的路由配置,所以跳转并不能完全以hash
的方式跳转,但是外层微前端框架的 url 是固定的不能改变,内部的微前端项目就无法使用windows.replace
进行跳转。
思考
所以到底什么是微前端,它到底尝试或者已经解决什么问题?
后端微服务化为服务提供了良好的横向扩展能力,同时能让各服务可以方便的提供给其他微服务调用。类比微前端我认为真正的微前端应该是可以各前端项目暴露组件,其他前端项目可以直接导入复用。但是现有的微前端框架只是让异构应用(vue/angular/react 等)能在一个 layout 内不使用iframe
的方式跳转并展示出来,一些高级功能需要修改存量系统,添加一些监听代码,响应事件并作出处理。
但是对于存量系统,比如上面我设计的架构,并不能完全适配,修改时就会出现到底该谁来修改问题。比如我为了保证不引入新坑,我拒绝项目组 A 要求的在 axios 中加入域名/IP 的请求。
所谓的”微前端”框架,我认为更像是一种新的开发模式,开发模式的意思是所有的前端项目可以不强制使用同一技术栈,且还都在开发中,可以针对微前端框架做编码上的修改和定制,但是对于存量已上线并正常运行了一段时间,甚至当初的开发人员已不在了的情况下,擅自修改现有开发规范、修改底层配置等很可能会引入一些新的问题让存量系统项目组的维护变得痛苦。