qiankun 中遇见的问题集合

news/2024/12/18 20:33:21/文章来源:https://www.cnblogs.com/Grewer/p/18615800

本文中的微前端基于 qiankun 框架

多个子应用共存

如果需要多个子应用同时共存,在管理就有很多例子:

https://qiankun.umijs.org/zh/faq#如何同时激活两个微应用

registerMicroApps([// 自定义 activeRule{ name: 'reactApp', entry: '//localhost:7100', container, activeRule: () => isReactApp() },{ name: 'react15App', entry: '//localhost:7102', container, activeRule: () => isReactApp() },{ name: 'vueApp', entry: '//localhost:7101', container, activeRule: () => isVueApp() },
]);start({ singular: false });

而使用 loadMicroApp 也会更加灵活:

class App extends React.Component {containerRef = React.createRef();microApp = null;componentDidMount() {this.microApp = loadMicroApp({name: 'app1',entry: '//localhost:1234',container: this.containerRef.current,props: { brand: 'qiankun' },});}componentWillUnmount() {this.microApp.unmount();}componentDidUpdate() {this.microApp.update({ name: 'kuitos' });}render() {return <div ref={this.containerRef}></div>;}
}

这里对于多个子应用同时存在的方案不再赘述,要解决的是多个子应用同时存在时,css的冲突问题:

解决方法 1:通用的挂载入口解决

比如你使用的是 antd 组件库, 在他的配置 provider 中有挂载节点的配置:

https://ant-design.antgroup.com/components/config-provider-cn

import React from 'react';import { ConfigProvider } from 'antd';// ...const Demo: React.FC = () => (<ConfigProvider direction="rtl" getPopupContainer={()=>{// 通过判断 当前是否某个特殊环境,如微前端环境// 返回不同的 domreturn document.getElementById('content-id')// 或者返回默认return document.body}}><App /></ConfigProvider>);export default Demo;

当然这种方法适用于只有 antd 组件的场景,一旦使用三方的组件,没有任何挂载 dom 的入口 API就会抓瞎

这个时候,如果你能改三方包则需要一个个检查和升级,那么有没有一个方法可以解决所有问题呢?

方案 2: 代理 API

通用型方案出现,通过代理 api 的操作来解决挂载问题

// 保存原始的 document.body.appendChild 方法
const originalAppendChild = document.body.appendChild;// customDom 是子应用的根节点元素
const proxiedAppendChild = new Proxy(document.body.appendChild, {apply(target, thisArg, argumentsList) {// 在这里可以添加自定义逻辑console.log('即将添加一个新元素到自定义DOM');// 获取要添加的元素const elementToAdd = argumentsList[0];// 将元素添加到自定义DOM元素中customDom.appendChild(elementToAdd);// 如果需要在添加到自定义DOM后还有其他操作,可以在这里添加return elementToAdd;}
});

在切到到气筒页面,如主应用的某些页面,或其他技术站页面,再或者是 iframe 页面时,需要取消代理:

// 取消代理的函数
function cancelAppendChildProxy() {if (document.body.appendChild === proxiedAppendChild) {document.body.appendChild = originalAppendChild;console.log('已成功取消对 document.body.appendChild 方法的代理');} else {console.log('当前 document.body.appendChild 方法未处于代理状态');}
}

注意: 在代理 document.body.appendChild 的函数时,对应的 document.body.removeChild 也需要添加。

这里为了简化代码,方便展示,也去掉了很多特殊场景的判断。

如果需要考虑兼容性,可以不使用 Proxy, 使用最简单的赋值方法即可:

// 保存原始的 document.body.appendChild 方法
const originalAppendChild = document.body.appendChild;// customDom 是子应用的根节点元素
const proxyAppendChild = (dom) => {const target = cutomDom || document.body;// 记得加上 try catch 避免报错// 其他的一些特殊场景的判断target[`appendChild`](dom);
}document.body['appendChild'] = proxyAppendChild;

在这里还有个特殊场景需要注意:

16 升级到 17 后,React 将事件委托到 ReactDOM 挂载的根节点上,比如 div#app,而不再是原来 document

所以在我们添加子应用渲染 dom 节点时,需要注意不要 appendChild 到更高一层的节点上,不然在点击 modal 组件时,里面的按钮都会失效

子应用保活

按照正常情况来说, 微前端应用应该不需要保活,但是形式比人强,有些客户、需求就必须要这样做。

主要的思路是挂载的 dom ,我这使用的是这个仓库:react-activation 来实现 keep alive

最终将 dom 挂载到不被 react-router 影响的页面上即可。

注意:即使页面不会显示,但是我们的应用里有 react-router 时,还会有对应的路由映射机制,某些特殊的路由判断需要去除,比如: 404 的判断等等

如何提取出公共的依赖库

官方不太推荐将运行时共用, 即使共用也只推荐使用了一个方案:external , 在主应用中加载必要的公共依赖

在如今 MF 微前端大火的情况下,后续我将调研此方案,应该能给出更好的解决办法;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/855013.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

批量数据传入数据库方法方案

前端处理好的数据,不是1笔2笔的问题,而是每次几笔或是大批量数据传入数据库。实际上,还是讲求效率与性能。在Insus.NET的博客中,找到几篇以前的随笔,1 使用SqlBulkCopy导入数据至MS SQL Server https://www.cnblogs.com/insus/p/3779879.html 2 ASP.NET MVC一次删除多…

玩家结构体和枚举

玩家结构体包含了玩家类型,玩家位置,玩家初始化构造函数还有画自己的函数方法玩家结构体 enum E_PlayerType//玩家类型的枚举 {Player,Robot, } struct Player {public E_PlayerType type;//用地图上的索引代替坐标public mapIndex;public Player(int index,E_PlayerType typ…

Windows Server 2019 配置PHP环境(图文教程)

操作系统:Windows Server 2019运行模式:IIS10 + fastcgi + PHP(安装IIS的时候选择上CGI)软件版本:MySQL 5.7.37 解压版 / PHP 7.4.29 / PHP Manager 1.5.0 / phpMyAdmin 5.1.31、MySQL 5.7.37 解压版安装: 为什么我会选择解压版而不是安装版?一是因为安装版没有64位版本…

微服务的终极 Golang 框架:GoFr

微服务的终极 Golang 框架:GoFr 原创 南丞 PFinalClub2024年12月18日 13:18 上海PFinalClub 一个有信念者所开发出的力量,大于99个只有兴趣者。 113篇原创内容公众号微服务的终极 Golang 框架:GoFr 前言 Go 语言因其出色的并发处理能力和简洁的语法,成为开发微服务的理想选…

R机器学习:朴素贝叶斯算法的理解与实操

最近又看了很多贝叶斯算法的一些文章,好多的文章对这个算法解释起来会放一大堆公式,对代数不好的人来说真的很头疼。本文尝试着用大白话写写这个算法,再做个例子,帮助大家理解和运用。Naive Bayes is a probabilistic machine learning algorithm based on the Bayes Theor…

[Linux]线程

线程 页表 每个进程都有一个虚拟地址空间,虚拟地址通过页表的映射找到对应的物理地址。那页表是如何完成虚拟地址到物理地址的映射的呢?其实一个程序在磁盘上的时候就以4KB为单位被划分成块,每一块称为页帧;而物理内存同样是以4KB为单位被划分,每一块称为页框。所以程序都…

Java框架 —— SpringMVC

MVC 分层MVC:Model View Controller(模型-视图-控制器)模型(Model):处理数据逻辑的部分;在web应用中,他通常包含与数据库交互的代码,负责数据的存储、检索和更新视图(View):将数据渲染为用户界面,视图只展示页面,不包含业务逻辑控制器(Controller):模型和视图…

2024-12-18 17 55 记录 Cambly trip`s summary and wher 1607b517085581159d14fe7750337be7

2024-12-18 17:55 记录 Cambly trip`s summary and where is the next ?https://tingwu.aliyun.com/doc/transcripts/g2y8qevxaayxnbeo?sl=1# 《2024-12-18 17:55 记录 Cambly trip`s summary and where is the next ?》1. 全文摘要 对话讲述了一个人通过使用美好的旅行来…

实验六 模板类、文件I/O和异常处理

1、实验任务一 Complex.hpp#pragma once#include <iostream> #include <stdexcept>// 声明 //////////////////////////////////////////////////// // 复数模板类声明 template<typename T> class Complex { public:Complex(T r = 0, T i = 0);Complex(cons…

免费设计Logo的新神器Slea.ai

使用Slea.ai,你可以在几分钟内设计出专业、高质量的Logo,支持多种场景应用,免费下载,实现自定义设计。品牌打造从未如此轻松!作为一名注重品牌形象的创作者或企业主,你是否苦于设计一款专业又独特的Logo?今天我要向大家推荐一个超级实用的网站——Slea.ai,它是一款免费的…

MOS管的寄生电容

我们经常看到,在电源电路中,功率MOS管的G极经常会串联一个小电阻,几欧姆到几十欧姆不等,那么这个电阻用什么作用呢? 这个电阻的作用有2个作用:限制G极电流,抑制振荡。 限制G极电流MOS管是由电压驱动的,是以G级电流很小,但是因为寄生电容的存在,在MOS管打开或关闭的时…