阿里云控制台前端框架-阿里云web框架
2016年,ThoughtWorks提出了一个类似于微服务的概念,叫做“Micro Frontend”。 此后,这个概念逐渐登陆web领域,各种微前端框架在前端技术领域层出不穷。 本文将为您介绍微前端的概念和意义,带您走近微前端框架,揭秘那些“不为人知”的巧妙技术实现。
概念
什么是微前端? 虽然它是在2016年提出的,但直到今天,我们只能描述它的轮廓,而不能给它一个明确的定义。 以下是笔者看过的关于微前端概念的一些阐述:
微前端是一种类似于微服务的架构。 它将微服务的概念应用到浏览器端,即将单页面前端应用从单一的单一应用转变为将多个小前端应用聚合为一个的应用。 每个前端应用程序也可以独立开发和部署。 同时,它们也可以并行开发。 ——《前端架构:从入门到微前端》
微前端背后的想法是将网站或 Web 应用程序视为由独立团队拥有的功能组合。 每个团队都有一个独特的业务或任务领域,做他们专注和专注的事情。 团队是跨职能的,开发从数据库到用户界面的端到端功能。 ——翻译,micro-frontends.org
微前端的核心价值在于“技术栈无关”,这是它诞生的原因,或者说这是可以说服我采用微前端方案的原因。 ——kuitos阿里云控制台前端框架,乾坤作者,2020.11.20 晚上阿里云微前端线下沙龙
真正需要解决的是,当技术更新时,应用能够兼容不同世代的应用。
微前端是一个架构,不是一个独立的技术点。 我个人是从两个角度来看待微前端的,一个是应用结构,微前端是多个小应用聚合为一个的应用形态; 另一个是团队意识,在微前端架构下,每个团队只负责独立(封闭)),需要包含从服务端到客户端,团队合作的意识与以往大不相同。
微前端解决方案
如何从技术上实现微前端的概念? 在前端技术领域,出现了以下三种技术方案:
基于接口协议:子应用根据协议导出若干个接口,主应用在运行时调用子应用导出的这些接口
基于沙箱隔离:主应用创建隔离环境阿里云控制台前端框架,子应用基本不需要考虑运行在什么环境中,可以按照普通的开发思路进行开发
基于模块协议:主应用把子应用当做一个模块,与模块的使用方式没有区别
这三种选择各有优缺点,我们不能立即断定哪个更好。
方案类型 典型技术优缺点 共同点
接口协议single-spa比较自由,可以独立封装,不能满足很多场景
子应用/模块互不干扰
技术栈独立
沙盒隔离 qiankun 开发思路简单直接 沙盒带来的性能等问题
模块协议webpack模块联合使用模块思维理解没有构建工具不能使用引用
就目前的市场情况来看,基于沙盒隔离的微前端解决方案占据主导地位,即本文将要阐述的微前端框架也是此类解决方案。 其中,笔者认为最重要的一点是,基于沙箱隔离的方案,可以让应用以最低的成本从原来的单体大应用迁移到微前端架构。
微前端框架的比较评估
微前端框架是用于快速将网站或其他技术栈切换到微前端架构的底层引擎。 市场上有许多微前端框架。 作者在2021年做了一个合集,比较典型。 (虽然后来出现了更新的微前端框架,但大部分原理都是一样的,所以下面的框架就足够了。)
Mooa:一个基于 Angular 的微前端服务框架
Single-Spa:最早的微前端框架,兼容多种前端技术栈。
乾坤:基于阿里巴巴开源的微前端框架Single-Spa。
Icestark:阿里飞冰微前端框架,兼容多种前端技术栈
console-os是阿里云控制台系统孵化的微前端解决方案,定位为企业级微前端系统解决方案。
Module Federation:webpack给出的微前端解决方案
Luigi:一个复杂的分布式前端应用解决方案
FrintJS:独立解决依赖关系的微前端框架
PuzzleJS:一套复杂的前后端编译时结合的微前端解决方案
ngx-planet:基于 Angular 的微前端框架
麦饭(mfy):一个精致简洁的微前端框架
除了webpack的federal module方案需要结合构建比较特殊,其他方案都是在运行时完成应用聚合。 “子应用独立运行”是指子应用可以不放置在基础应用环境中自行运行,便于不同基础的调试和引入。 “子应用嵌套子应用”是一个比较特殊的点,目前市面上能做到的框架并不多。
微前端框架核心技术
在微前端架构中,有“主应用”和“子应用”两个层次,微前端框架的主要任务是让子应用在主应用中有效运行。 如上所述,目前很多微前端框架都是基于(或支持)沙箱隔离实现主从应用运行机制。 笔者实现的小微前端框架“麦饭”也属于此类。 因此,本文只深入讲解这类微前端框架的技术原理和实现。 微前端框架要解决的核心问题是资源加载和环境隔离。 此外,还有路由、通信等问题。
资源加载
微前端框架需要从服务端拉取子应用的代码文件,完成子应用的解析挂载和运行。 除了webpack的模块联合方案,现在常见的方案有两种,即:以JS文件为入口; 使用 HTML 文件作为入口点。 以JS文件为入口,可以直接运行JS脚本获取JS导出的内容,但这种方式只能加载脚本资源,无法加载CSS等样式资源。 以HTML文件为入口,通过HTML文件中的文件引用,可以一起加载所有对应的JS和CSS文件。 而且,网站使用HTML文件作为入口,正好可以开发子应用。作者是按照web开发的思路来编写子应用的。 作者在写麦饭框架的时候,希望子应用可以直接运行,所以使用了HTML作为入口文件。 开发人员使用特殊的 importSource 函数来导入入口文件。 该函数可以根据入口文件解析并缓存子应用的所有资源。
解析资源
框架获取HTML入口文件地址后,通过HTTP请求获取文件内容,并解析内容。 解析时需要解析资源树,即通过HTML读取所有资源文件,如link、script[src]。 在阅读资源的时候,可能还需要阅读资源本身引入的资源。 大致逻辑如下:在解析过程中,还需要根据registerMicroApp(麦饭提供的注册接口)的配置来决定如何处理CSS规则。通过解析获取CSS的trick是通过
预加载/延迟加载
在设计上,子应用程序的资源可以以两种可选的形式加载。 在麦饭中,如果想提前预加载子应用资源,可以在registerMicroApp时直接传入importSource(...)。 一旦执行此函数,它将请求资源并缓存它们。 但是,如果不需要预加载,而想在子应用需要进入界面时(或打算让子应用进入界面时)加载资源,那么configure() => importSource( ...) ,此配置将仅在子应用程序执行 bootstrap 时请求资源。
环境隔离
环境隔离是微前端框架实现的核心技术难点。 由于子应用的开发团队是分开的,因此两个子应用之间可能存在相互污染的问题。 这就需要微前端框架实现一种能力,让子应用在自己隔离的环境中运行,不至于干扰其他子应用。 应用造成污染。 目前可用于解决环境隔离的方案有:
iframe:样式与脚本运行隔离,缺点是无法全屏弹出图层
ShadowDOM:样式隔离,缺点是弹出层挂在document.body下,样式放在ShadowDOM里面,弹出层无法正确渲染
快照沙箱
代理沙箱
还有一些框架将这些解决方案结合起来,在不同的场景中主动或被动地使用其中的一种。 其中,快照沙箱和代理沙箱是两种比较独特的技术方案:
快照沙箱
多个子应用在页面上相互切换,子应用脚本的运行会污染当前全局环境。 快照沙箱就是用来解决这种污染的。 该方案只适用于一次只运行一个子应用的场景,比如腾讯云控制台。 当子应用程序进入界面时,对窗口上的所有属性进行快照。 子应用程序运行时可以修改窗口。 当子应用程序离开界面时,清理窗口,然后将快照上的属性重新添加到窗口,恢复子应用程序挂载前的窗口。