微前端解决方案 - qiankun 2.0

2024-05-09 08:58

本文主要是介绍微前端解决方案 - qiankun 2.0,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Announcing qiankun@2.0

2019 年 6 月,微前端框架 qiankun 正式发布了 1.0 版本,在这一年不到的时间内,我们收获了 4k+ star,收获了来自 single-spa 官方团队的问候,支撑了阿里 200+ 线上应用,也成为社区许多团队选用的微前端解决方案。

在今天,qiankun 将正式发布 2.0 版本。

qiankun@2.0 带来了一些新能力的同时,只做了很小的 API 调整,1.x 的用户可以很轻松的迁移到 2.x 版本,详细信息见下方 升级指南 小节。

qiankun 简介

可能有的朋友还不太了解 微前端 和 qiankun 是什么。

微前端是最近一年国内前端领域被频繁提及的关键字,虽然它并不是一个全新的领域/技术,但很显然在当今越来越多的前端应用即将步入第 3 个、第 5 个甚至更久的年头的背景下,如何给 巨石应用/遗产应用 注入新鲜的技术血液已经成为我们不得不正视的问题,而微前端正是解决这类问题的一个非常合适的解决方案。

qiankun 是一个生产可用的微前端框架,它基于 single-spa,具备 js 沙箱、样式隔离、HTML Loader、预加载 等微前端系统所需的能力。qiankun 可以用于任意 js 框架,微应用接入像嵌入一个 iframe 系统一样简单。

更多信息可以查阅我们的 官方站点

定位变化

qiankun 2.0 带来的最大变化便是 qiankun 的定位将由 微前端框架 转变为 微应用加载器

此前 qiankun 的典型应用场景是 route-based 的控制台应用,做为一个微应用的聚合框架而被使用。

如上图所示,在这种场景下,一个负责聚合与切换的主应用 与 多个相互独自的微应用 一起构成了整个大的微前端应用,一般来说页面上同一时间活跃着的也往往只有一个微应用。

而这是微前端的场景之一,在另外一些场景下,你应该可以在同一个页面中,加载多个不同的微应用,每个微应用都是主应用的组成部分 或者是 提供一些增强能力,这种场景可以说是微应用粒度的前端组件化。

因此,qiankun@2.0 将跳出 route-based 的微前端场景,提供更加通用的微应用加载能力,让用户可以更加自由的组合微应用来搭建产品。

本次升级带来了什么?

新功能

  • 支持多应用并行及多实例沙箱
  • 支持手动 加载/卸载 微应用
  • 支持 IE11 沙箱兼容
  • 官方的极简微应用通信方案
  • 支持基于 Shadow DOM 的样式隔离

此外我们还做了

  • 升级 single-spa 到 5.x 版本
  • 更灵活的 prefetch 的定制策略
  • 配套的 webpack 插件
  • 更友好的部署场景支持,如自动为微应用注入运行时 publicPath 等
  • 更简单易懂的 API,重构了许多代码,使其更清晰和更具扩展性
  • 修复了一些 bug

另外我们还升级了相应的 umi qiankun plugin,在 umi 场景下你可以这样去加载一个微应用:

import { MicroApp } from 'umi';function MyPage() {return (<div><MicroApp name="qiankun"/></div>);
}

发布日志

多应用支持

在 qiankun@1.x 中,我们的沙箱、样式隔离等机制只能对单一微应用场景生效,多个微应用共存的支持能力尚不完备。

而在 2.0 版本中,我们终于完善了这一功能,现在,你可以同时激活多个微应用,而微应用之间可以保持互不干扰。

在多应用场景下,每个微应用的沙箱都是相互隔离的,也就是说每个微应用对全局的影响都会局限在微应用自己的作用域内。比如 A 应用在 window 上新增了个属性 test,这个属性只能在 A 应用自己的作用域通过 window.test 获取到,主应用或者其他微应用都无法拿到这个变量。

但是注意,页面上不能同时显示多个依赖于路由的微应用,因为浏览器只有一个 url,如果有多个依赖路由的微应用同时被激活,那么大概率会导致其中一个 404。

为了更方便的同时装载多个微应用,我们提供了一个全新的 API loadMicroApp ,用于手动控制微应用:

import { loadMicroApp } from 'qiankun';/** 手动加载一个微应用 */
const microApp = loadMicroApp({name: "microApp",entry: "https://localhost:7001/micro-app.html",container: "#microApp"}
)// 手动卸载
microApp.mountPromise.then(() => microApp.unmount());

这也是 qiankun 作为一个应用加载器的使用方式。

基于这个 api,你可以很容易的封装一个自己的微应用容器组件,比如:

class MicroApp extends React.Component {microAppRef = null;componentDidMount() {const { name, entry } = this.props;this.microAppRef = loadMicroApp({ name, entry, container: '#container' });}componentWillUnmount() {this.microAppRef.mountPromise.then(() => this.microAppRef.unmount());}render() {return <div id="container"/>;}
}

兼容 IE11 的沙箱能力

在 qiankun issue 区域呼声最高的就是 IE 的兼容,有不少小伙伴都期待 qiankun 能够在 IE 下使用。

qiankun 1.x 在 IE 使用的主要阻碍就是 qiankun 的沙箱使用了 ES6 的 Proxy,而这无法通过 ployfill 等方式弥补。这导致 IE 下的 qiankun 用户无法开启 qiankun 的沙箱功能,导致 js 隔离、样式隔离这些能力都无法启用。

为此,我们实现了一个 IE 特供的快照沙箱,用于这些不支持 Proxy 的浏览器;这不需要用户手动开启,在代理沙箱不支持的环境中,我们会自动降级到快照沙箱。

注意,由于快照沙箱不能做到互相之间的完全独立,所以 IE 等环境下我们不支持多应用场景,  singlur 会被强制设为 true。

基于 shadow DOM 的样式隔离

样式隔离也是微前端面临的一个重要问题,在 qiankun@1.x 中,我们支持了微应用之间的样式隔离(仅沙箱开启时生效),这尚存一些问题:

  1. 主子应用之间的样式隔离依赖手动配置插件处理
  2. 多应用场景下微应用之间的样式隔离亟待处理

为此,我们引入了一个新的选项, sandbox: { strictStyleIsolation?: boolean } 。

在该选项开启的情况下,我们会以 Shadow DOM 的形式嵌入微应用,以此来做到应用样式的真正隔离:

import { loadMicroApp } from 'qiankun'loadMicroApp({xxx}, { sandbox: { strictStyleIsolation: true } });

Shadow DOM 可以做到样式之间的真正隔离(而不是依赖分配前缀等约定式隔离),其形式如下:

图片来自  MDN

在开启 strictStyleIsolation 时,我们会将微应用插入到 qiankun 创建好的 Shadow Tree 中,微应用的样式(包括动态插入的样式)都会被挂载到这个 Shadow Host 节点下,因此微应用的样式只会作用在 Shadow Tree 内部,这样就做到了样式隔离。

但是开启 Shadow DOM 也会引发一些别的问题:

一个典型的问题是,一些组件可能会越过 Shadow Boundary 到外部 Document Tree 插入节点,而这部分节点的样式就会丢失;比如 antd 的 Modal 就会渲染节点至 ducument.body ,引发样式丢失;针对刚才的 antd 场景你可以通过他们提供的 ConfigProvider.getPopupContainer API 来指定在 Shadow Tree 内部的节点为挂载节点,但另外一些其他的组件库,或者你的一些代码也会遇到同样的问题,需要你额外留心。

此外 Shadow DOM 场景下还会有一些额外的事件处理、边界处理等问题,后续我们会逐步更新官方文档指导用户更顺利的开启 Shadow DOM。

所以请根据实际情况来选择是否开启基于 shadow DOM 的样式隔离,并做好相应的检查和处理。

官方的极简通信方案

微前端场景下,我们认为最合理的通信方案是通过 URL 及 CustomEvent 来处理。但在一些简单场景下,基于 props 的方案会更直接便捷,因此我们为 qiankun 用户提供这样一组 API 来完成应用间的通信:

主应用创建共享状态:

import { initGloabalState } from 'qiankun';initGloabalState({ user: 'kuitos' });

微应用通过 props 获取共享状态并监听:

export function mount(props) {props.onGlobalStateChange((state, prevState) => {console.log(state, prevState);});
};

更详细的 API 介绍可以查看官方文档。

我们会继续为大家带来什么

除了基本的日常维护、bugfix 之外,我们还会尝试走的更远:

  1. 官方支持的 qiankun webpack 插件,解决一些由于配置不当出现的问题
  2. 自定义的沙箱规则
  3. 微应用嵌套支持
  4. 更友好的调试体验
  5. 与 Webpack5 Module Federation 的结合,提供官方的使用指导或插件
  6. 更多的实验性(experimental)尝试,如基于原生 Portal 标签的微应用渲染,基于运行时的更轻量的样式隔离方案。

升级指南

2.0 版本 调整了相当多的内部 API 名字,但大家使用的外部 API 变化并不大(基本完全兼容 1.x),你可以在十分钟内完成升级。

render 更改为 container

import { registerMicroApps } from 'qiankun'registerMicroApps([{name: 'react16',entry: '//localhost:7100',
-     activeRule: location => location.pathname.startsWith('/react'),
+     activeRule: '/react',
-     render: renderFn,
+     container: '#subapp-viewport',},]
)

现在你可以简单的指定一个挂载节点即可,而不用自己手写对应的 render 函数了。简单场景下 activeRule 配置也不需要再手写函数了(当然还是支持自定义函数),只需要给出一个前缀规则字符串即可,同时支持 react-router 类的动态规则,如 /react/:appId/name (来自 single-spa 5.x 的支持)。

同时,微应用收到的 props 中会新增一个 container 属性,这就是你的挂载节点的 DOM,这对处理动态添加的容器以及开启了 Shadow DOM 场景下非常有用。

注意,旧的 render 配置依然可以使用,我们做了兼容处理方便不想升级的用户;但 render 存在时,container 就不会生效。

start 的配置变化

因为我们引入了一些新的能力,因此 start 的配置也发生了一些变化:

import { start } from 'qiankun'start({
-  jsSandbox: true,
+  sandbox: {
+    strictStyleIsolation: true
+  }
})

新的 API loadMicroApp

这个 API 用于手动挂载一个微应用

/** 用于加载一个微应用 */
loadMicroApp(app: LoadableApp, configuration?: FrameworkConfiguration)

使用详情可见上面 多应用支持 小节。

这篇关于微前端解决方案 - qiankun 2.0的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/972962

相关文章

使用Python构建智能BAT文件生成器的完美解决方案

《使用Python构建智能BAT文件生成器的完美解决方案》这篇文章主要为大家详细介绍了如何使用wxPython构建一个智能的BAT文件生成器,它不仅能够为Python脚本生成启动脚本,还提供了完整的文... 目录引言运行效果图项目背景与需求分析核心需求技术选型核心功能实现1. 数据库设计2. 界面布局设计3

Java.lang.InterruptedException被中止异常的原因及解决方案

《Java.lang.InterruptedException被中止异常的原因及解决方案》Java.lang.InterruptedException是线程被中断时抛出的异常,用于协作停止执行,常见于... 目录报错问题报错原因解决方法Java.lang.InterruptedException 是 Jav

kkFileView在线预览office的常见问题以及解决方案

《kkFileView在线预览office的常见问题以及解决方案》kkFileView在线预览Office常见问题包括base64编码配置、Office组件安装、乱码处理及水印添加,解决方案涉及版本适... 目录kkFileView在线预览office的常见问题1.base642.提示找不到OFFICE组件

SpringBoot监控API请求耗时的6中解决解决方案

《SpringBoot监控API请求耗时的6中解决解决方案》本文介绍SpringBoot中记录API请求耗时的6种方案,包括手动埋点、AOP切面、拦截器、Filter、事件监听、Micrometer+... 目录1. 简介2.实战案例2.1 手动记录2.2 自定义AOP记录2.3 拦截器技术2.4 使用Fi

从入门到精通详解LangChain加载HTML内容的全攻略

《从入门到精通详解LangChain加载HTML内容的全攻略》这篇文章主要为大家详细介绍了如何用LangChain优雅地处理HTML内容,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录引言:当大语言模型遇见html一、HTML加载器为什么需要专门的HTML加载器核心加载器对比表二

WinForm跨线程访问UI及UI卡死的解决方案

《WinForm跨线程访问UI及UI卡死的解决方案》在WinForm开发过程中,跨线程访问UI控件和界面卡死是常见的技术难题,由于Windows窗体应用程序的UI控件默认只能在主线程(UI线程)上操作... 目录前言正文案例1:直接线程操作(无UI访问)案例2:BeginInvoke访问UI(错误用法)案例

Spring Security常见问题及解决方案

《SpringSecurity常见问题及解决方案》SpringSecurity是Spring生态的安全框架,提供认证、授权及攻击防护,支持JWT、OAuth2集成,适用于保护Spring应用,需配置... 目录Spring Security 简介Spring Security 核心概念1. ​Securit

MySQL逻辑删除与唯一索引冲突解决方案

《MySQL逻辑删除与唯一索引冲突解决方案》本文探讨MySQL逻辑删除与唯一索引冲突问题,提出四种解决方案:复合索引+时间戳、修改唯一字段、历史表、业务层校验,推荐方案1和方案3,适用于不同场景,感兴... 目录问题背景问题复现解决方案解决方案1.复合唯一索引 + 时间戳删除字段解决方案2:删除后修改唯一字

Java 线程安全与 volatile与单例模式问题及解决方案

《Java线程安全与volatile与单例模式问题及解决方案》文章主要讲解线程安全问题的五个成因(调度随机、变量修改、非原子操作、内存可见性、指令重排序)及解决方案,强调使用volatile关键字... 目录什么是线程安全线程安全问题的产生与解决方案线程的调度是随机的多个线程对同一个变量进行修改线程的修改操

全面解析MySQL索引长度限制问题与解决方案

《全面解析MySQL索引长度限制问题与解决方案》MySQL对索引长度设限是为了保持高效的数据检索性能,这个限制不是MySQL的缺陷,而是数据库设计中的权衡结果,下面我们就来看看如何解决这一问题吧... 目录引言:为什么会有索引键长度问题?一、问题根源深度解析mysql索引长度限制原理实际场景示例二、五大解决