什么是微前端?
微前端(Micro-Frontends)是一种类似于微服务的架构,它将微服务的理念应用于浏览器端,即将 Web 应用由单一的单体应用转变为多个小型前端应用聚合为一的应用。各个前端应用还可以独立运行、独立开发、独立部署。微前端不是单纯的前端框架或者工具,而是一套架构体系
实现微前端有哪些方案
方案 | 描述 | 优点 | 缺点 |
---|---|---|---|
Nginx路由转发 | 通过Nginx配置反向代理来实现不同路径映射到不同应用,例如www.abc.com/app1对应app1,www.abc.com/app2对应app2,这种方案本身并不属于前端层面的改造,更多的是运维的配置。 | 简单,快速,易配置 | 在切换应用时会触发浏览器刷新,影响体验 |
iframe嵌套 | 父应用单独是一个页面,每个子应用嵌套一个iframe,父子通信可采用postMessage或者contentWindow方式 | 实现简单,子应用之间自带沙箱,天然隔离,互不影响 | iframe的样式显示、兼容性等都具有局限性;太过简单而显得low |
Web Components | 每个子应用需要采用纯Web Components技术编写组件,是一套全新的开发模式 | 每个子应用拥有独立的script和css,也可单独部署 | 对于历史系统改造成本高,子应用通信较为复杂易踩坑 |
组合式应用路由分发 | 每个子应用独立构建和部署,运行时由父应用来进行路由管理,应用加载,启动,卸载,以及通信机制 | 纯前端改造,体验良好,可无感知切换,子应用相互隔离 | 需要设计和开发,由于父子应用处于同一页面运行,需要解决子应用的样式冲突,变量对象污染,通信机制等技术点 |
组合式应用路由分发方案改造成本中等并且能满足大部分需求,也不影响各前端应用的体验,是当下各个业务普遍采用的一种方案
微前端由哪些模块组成
当下微前端主要采用的是组合式应用路由方案,该方案的核心是“主从”思想,即包括一个基座(MainApp)应用和若干个微(MicroApp)应用,基座应用大多数是一个前端SPA项目,主要负责应用注册,路由映射,消息下发等,而微应用是独立前端项目,这些项目不限于采用React,Vue,Angular或者JQuery开发,每个微应用注册到基座应用中,由基座进行管理,但是如果脱离基座也是可以单独访问,基本的流程如下图所示:
一个微前端的基座框架需要解决以下问题:
- 路由切换的分发问题。
- 主微应用的隔离问题。
- 通信问题。
微前端的路由分发
基座应用,是整个应用的入口,一般是由以下几步构成:
- 要想展示微应用的页面,要能先拉取到微应用的页面内容, 这就需要远程拉取机制。
- 远程拉取机制通常会采用fetch API来首先获取到微应用的HTML内容,然后通过解析将微应用的JavaScript和CSS进行抽离,采用eval方法来运行JavaScript,并将CSS和HTML内容append到基座应用中留给微应用的展示区域,当微应用切换走时,同步卸载这些内容,这就构成的当前应用的展示流程。
- 而目前针对远程拉取机制这套流程,已有现成的库来实现,可以参考import-html-entry。
对于路由分发而言,以采用vue-router开发的基座SPA应用来举例,主要是下面这个流程:
当浏览器的路径变化后,vue-router会监听hashchange或者popstate事件,从而获取到路由切换的时机。
最先接收到这个变化的是基座的router,通过查询注册信息可以获取到转发到那个微应用,经过一些逻辑处理后,采用修改hash方法或者pushState方法来路由信息推送给微应用的路由,微应用可以是手动监听hashchange或者popstate事件接收,或者采用React-router,vue-router接管路由,后面的逻辑就由微应用自己控制。
微前端的应用隔离
CSS隔离:当主应用和微应用同屏渲染时,就可能会有一些样式会相互污染,如果要彻底隔离CSS污染,可以采用CSS Module 或者命名空间的方式,给每个微应用模块以特定前缀,即可保证不会互相干扰,可以采用webpack的postcss插件,在打包时添加特定的前缀。
而对于微应用与微应用之间的CSS隔离就非常简单,在每次应用加载时,将该应用所有的link和style 内容进行标记。在应用卸载后,同步卸载页面上对应的link和style即可。
JavaScript隔离:每当微应用的JavaScript被加载并运行时,它的核心实际上是对全局对象Window的修改以及一些全局事件的改变,例如jQuery这个js运行后,会在Window上挂载一个window.$对象,对于其他库React,Vue也不例外。为此,需要在加载和卸载每个微应用的同时,尽可能消除这种冲突和影响,最普遍的做法是采用沙箱机制(SandBox)。
沙箱机制的核心是让局部的JavaScript运行时,对外部对象的访问和修改处在可控的范围内,即无论内部怎么运行,都不会影响外部的对象。通常在Node.js端可以采用vm模块,而对于浏览器,则需要结合with关键字和window.Proxy对象来实现浏览器端的沙箱。
微前端的消息通信
应用间通信有很多种方式,当然,要让多个分离的微应用之间要做到通信,本质上仍离不开中间媒介或者说全局对象。所以对于消息订阅(pub/sub)模式的通信机制是非常适用的,在基座应用中会定义事件中心Event,每个微应用分别来注册事件,当被触发事件时再有事件中心统一分发,这就构成了基本的通信机制,流程如下图:
微前端有哪些框架
- Single-Spa:最早的微前端框架,兼容多种前端技术栈。
- Qiankun:基于Single-Spa,阿里系开源微前端框架。