Tech
导读
本文由浅到深地对微前端进行了概括性介绍,读者可以了解到微前端的概念、微前端的特点与价值、微前端的实现方案、一个微前端框架应具备的功能,以及微前端的适用场景。读者可以多关注下本文提到的各个开源的优秀的微前端实现方案,通过对比及借鉴来实现一套适合自身业务的微前端方案。
01
微前端是什么
传统的分而治之的策略已经无法应对现代 Web 应用的复杂性,因此衍生出了微前端这样一种新的架构模式,与后端微服务相同,它同样是延续了分而治之的设计模式,不过却以全新的方法来实现。微前端是一种由独立交付的多个前端应用组成整体的架构风格,将前端应用分解成一些更小、更简单的,能够独立开发、测试、部署的应用,并且在用户看来仍然是内聚的单个产品。
MicroFrontends:extending the microservice idea to frontenddevelopment; Techniques, strategies and recipes for building a modern web appwith multiple teams that can ship features independently.
02
微前端的特点与价值
2.1 独立与自治
独立开发、独立部署、独立自治代码库,从而可提升构建效率、改善交付效率。
2.2 技术栈无限定
技术栈自主性有利于多个不同技术栈的团队协同合作,技术栈的可平滑迁移也对旧有业务的不断迭代和技术升级带来较大的便利性。
2.3 颗粒化解耦与可组合
在大型的前端工程中,对于颗粒化解耦有很高的要求,常基于不同维度划分,例如业务类型颗粒化、技术服务类型颗粒化等等。各个微前端颗粒的可组合性又让多个可交付系列产品有很好的颗粒一致性和整体定制差异化,并能极大减少业务重复开发的资源浪费。
3.2 Module Federation/EMP(构建时确定依赖关系) 3.2.1 Module Federation: 多个独立的构建可以形成一个应用程序。这些独立的构建不会相互依赖,因此可以单独开发和部署。Multiple separate builds should form asingle application. These separate builds should not have dependencies betweeneach other, so they can be developed and deployed individually. This is oftenknown as Micro-Frontends, but is not limited to that. Module Federation提供了能在当前应用中远程加载其它服务器上应用的能力,基于此可以实现一个去中心化的应用部署群,每个应用是单独部署在各自的服务器,每个应用都可以引用其它应用,也能被其它应用所引用。通过new ModuleFederationPlugin配置被远程引用时的路径(exposes)、远程引用的应用、与其它应用之间可以共享的第三方依赖(shared)等。 由上可知,通过shared以及exposes可以将多个应用引入同一应用中进行管理,从而实现微前端架构。 3.2.2 EMP EMP是一个基于Webpack5Module Federation搭建的微前端解决方案。通过cdn加载微应用,可以动态更新微应用,微应用只需要部署一次便可以提供给任何基于Module Federation的应用使用。每个微应用间都可以引入其它的微应用,无中心应用的概念。可以选择只加载微应用中需要的部分。每一个应用都可以进行状态共享。 3.3 single-spa/qiankun/icestark/garfish(运行时确定依赖关系) 1.single-spa:Single-spa是一个用于前端微服务化的JavaScript前端解决方案,实现了路由劫持和应用加载(通过监听url change事件,在路由变化时匹配到子应用并进行渲染),其本身没有处理样式隔离和js执行隔离。其实,single-spa是一个子应用加载器与状态机的结合体。推荐阅读微前端框架之single-spa 从入门到精通 2.qiankun:qiankun是一个基于single-spa的微前端实现库。HTML entry接入方式。在主应用中注册微应用,当微应用信息注册完之后,一旦浏览器的url发生变化,便会自动触发qiankun的匹配逻辑,所有activeRule规则匹配上的微应用就会被插入到指定的container中,同时依次调用微应用暴露出的生命周期钩子(bootstrap、mount、unmount)。如果微应用不是直接跟路由关联的,也可以使用手动加载微应用的方式。 3.icestark:icestark通过微应用入口字段的配置进行应用的渲染,支持多种入口配置形式:url、entry(即html url)、entryContent(即html内容,用于解决html url不支持前端跨域访问的情况)、render/component(仅支持使用React的主应用)。为了能够让icestark响应页面路由的变化并对相应的微应用进行加载,icestark对两类路由事件进行了劫持,即history API的popstate和hashChange,以及window的路由事件pushState和replaceState。支持微模块,一种没有路由、粒度更小的挂件,通常是一个模块或页面,跟页面路由无关,可以随处挂载。 4.Garfish:当执行注册子应用相关信息并执行Garfish.run后,此时Garfish框架将会启动路由劫持能力,当浏览器的地址发生变化时,Garfish框架内部便会立即触发匹配逻辑,当应用符合匹配逻辑时将会自动将应用挂载至页面中(也可以手动通过某些事件触发来挂载),并依次触发子应用加载、渲染过程中的生命周期。支持HTML entry 和 JS entry。 3.4 Fronts(渐进式) Fronts:Fronts 是一个基于 Webpack 的 Module Federation API 设计的渐进式微前端框架。它强调颗粒间的去中心化依赖管理,并支持多种运行模式来满足不同的微前端架构需求。这个渐进式是指,如果前端工程的各个颗粒并不都支持Module Federation,它依然能以微前端的形式良好地运行,也能自由选择所需要的运行模式;并随着项目升级,可以逐一升级到支持 Module Federation,并最终根据实际需要建立和开启微前端版本控制系统。 3.5 Web Components 浏览器的原生组件,由三项主要技术组成,可以创建可重用的定制元素,不必担心代码冲突。
可以看出来,Web Components是有能力以组件加载的方式将微应用整合在一起实现微前端架构的一种手段:
当然,Web Components也有浏览器兼容性的限制。 micro-app:借鉴了Web Components的思想,通过Custom elements结合自定义的Shadow DOM,将微前端框架封装成一个类Web Component组件,从而实现基座应用对子应用的组件化渲染。 《前端架构从入门到微前端》一书中,将微前端的实现方案分为六种:路由分发、前端微服务化、微应用、微件化、iframe、Web Components。
根据注册的子应用,通过给定的url,加载约定格式的子应用入口,并挂载到给定位置。入口方式通常有两种:HTML和JS,JS做入口更纯粹,HTML做入口更易于旧项目改造。此外,提供预加载功能也很有必要,预加载是指在应用尚未渲染时提前加载资源并缓存,从而提升首屏渲染速度。
加载、挂载、更新、卸载等。
子应用的路由切换时,同步更新url;url改变时,同步更新子应用。
各个应用间可以便捷通信,局部通信、全局通信。
4.5沙箱隔离
1.JS隔离:
2.CSS隔离:
命名约定、自动Scope、Shadow DOM、自动卸载、弹窗遮罩。
对各种异常进行统一处理。
概括来讲,微前端主要解决了两个问题:
1.应用随着迭代变得越来越大,最终难以维护。
2.相对独立的几个应用需要融合为一个应用。
任何一个方案都有优缺点,也不可能适用于所有场景,是否适合的评判标准是收益要大于损失。
推荐阅读