微前端解决方案 - 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

相关文章

部署Vue项目到服务器后404错误的原因及解决方案

《部署Vue项目到服务器后404错误的原因及解决方案》文章介绍了Vue项目部署步骤以及404错误的解决方案,部署步骤包括构建项目、上传文件、配置Web服务器、重启Nginx和访问域名,404错误通常是... 目录一、vue项目部署步骤二、404错误原因及解决方案错误场景原因分析解决方案一、Vue项目部署步骤

前端原生js实现拖拽排课效果实例

《前端原生js实现拖拽排课效果实例》:本文主要介绍如何实现一个简单的课程表拖拽功能,通过HTML、CSS和JavaScript的配合,我们实现了课程项的拖拽、放置和显示功能,文中通过实例代码介绍的... 目录1. 效果展示2. 效果分析2.1 关键点2.2 实现方法3. 代码实现3.1 html部分3.2

在MySQL执行UPDATE语句时遇到的错误1175的解决方案

《在MySQL执行UPDATE语句时遇到的错误1175的解决方案》MySQL安全更新模式(SafeUpdateMode)限制了UPDATE和DELETE操作,要求使用WHERE子句时必须基于主键或索引... mysql 中遇到的 Error Code: 1175 是由于启用了 安全更新模式(Safe Upd

Python安装时常见报错以及解决方案

《Python安装时常见报错以及解决方案》:本文主要介绍在安装Python、配置环境变量、使用pip以及运行Python脚本时常见的错误及其解决方案,文中介绍的非常详细,需要的朋友可以参考下... 目录一、安装 python 时常见报错及解决方案(一)安装包下载失败(二)权限不足二、配置环境变量时常见报错及

Java下载文件中文文件名乱码的解决方案(文件名包含很多%)

《Java下载文件中文文件名乱码的解决方案(文件名包含很多%)》Java下载文件时,文件名中文乱码问题通常是由于编码不正确导致的,使用`URLEncoder.encode(filepath,UTF-8... 目录Java下载文件中文文件名乱码问题一般情况下,大家都是这样为了解决这个问题最终解决总结Java下

CSS弹性布局常用设置方式

《CSS弹性布局常用设置方式》文章总结了CSS布局与样式的常用属性和技巧,包括视口单位、弹性盒子布局、浮动元素、背景和边框样式、文本和阴影效果、溢出隐藏、定位以及背景渐变等,通过这些技巧,可以实现复杂... 一、单位元素vm 1vm 为视口的1%vh 视口高的1%vmin 参照长边vmax 参照长边re

Idea实现接口的方法上无法添加@Override注解的解决方案

《Idea实现接口的方法上无法添加@Override注解的解决方案》文章介绍了在IDEA中实现接口方法时无法添加@Override注解的问题及其解决方法,主要步骤包括更改项目结构中的Languagel... 目录Idea实现接China编程口的方法上无法添加@javascriptOverride注解错误原因解决方

CSS3中使用flex和grid实现等高元素布局的示例代码

《CSS3中使用flex和grid实现等高元素布局的示例代码》:本文主要介绍了使用CSS3中的Flexbox和Grid布局实现等高元素布局的方法,通过简单的两列实现、每行放置3列以及全部代码的展示,展示了这两种布局方式的实现细节和效果,详细内容请阅读本文,希望能对你有所帮助... 过往的实现方法是使用浮动加

css渐变色背景|<gradient示例详解

《css渐变色背景|<gradient示例详解》CSS渐变是一种从一种颜色平滑过渡到另一种颜色的效果,可以作为元素的背景,它包括线性渐变、径向渐变和锥形渐变,本文介绍css渐变色背景|<gradien... 使用渐变色作为背景可以直接将渐China编程变色用作元素的背景,可以看做是一种特殊的背景图片。(是作为背

CSS自定义浏览器滚动条样式完整代码

《CSS自定义浏览器滚动条样式完整代码》:本文主要介绍了如何使用CSS自定义浏览器滚动条的样式,包括隐藏滚动条的角落、设置滚动条的基本样式、轨道样式和滑块样式,并提供了完整的CSS代码示例,通过这些技巧,你可以为你的网站添加个性化的滚动条样式,从而提升用户体验,详细内容请阅读本文,希望能对你有所帮助...