qiankun:react18主应用 + 微应用 react18 + vue3

一:主应用
搭建react项目

npx create-react-app react-qiankun-main

安装Antd

npm install antd –save

在 index.js中引入

import { ConfigProvider } from "antd";
import zhCN from "antd/locale/zh_CN";
import "antd/dist/reset.css";
// ...
root.render(
  <ConfigProvider locale={zhCN}>
    <React.StrictMode>
      <App />
    </React.StrictMode>
  </ConfigProvider>
);

安装react-router :

npm i react-router-dom

在 index.js中引入

import { BrowserRouter } from "react-router-dom";

// …
 <BrowserRouter>
    <ConfigProvider locale={zhCN}>
      <React.StrictMode>
        <App />
      </React.StrictMode>
    </ConfigProvider>
  </BrowserRouter>
  

安装 qiankun :

 npm i qiankun -S

在主应用中注册微应用,在 index.js中引入

// …
import { registerMicroApps, start } from "qiankun";

registerMicroApps([
  {
    name: "react app", // 子应用的名称,必须唯一。
    entry: "//localhost:3004", // 子应用项目本地运行地址
    container: "#lyContainer", //  子应用的容器(子应用嵌入到主项目id为lyContainer的地方)
    activeRule: "/react-app", // 子应用激活时的路由规则(子应用路由)
  },
  {
    name: "vue app",
    entry: "//localhost:5173",
    container: "#lyContainer",
    activeRule: "/vue-app",
  },
]);

start();
// …

注:子应用嵌入到主应用的地方,id要跟index.js下registerMicroApps里面的container设置一致
在这里插入图片描述

修改App.js文件,将如下代码放入App.js

import React, { useState } from "react";
import "./App.css";
import {
  MenuFoldOutlined,
  MenuUnfoldOutlined,
  UserOutlined,
  VideoCameraOutlined,
} from "@ant-design/icons";
import { Layout, Menu, Button } from "antd";
import { NavLink } from "react-router-dom";
const { Header, Sider, Content } = Layout;

function App() {
  const [collapsed, setCollapsed] = useState(false);
  return (
    <div className="App">
      <Layout className="layout-container">
        <Sider trigger={null} collapsible collapsed={collapsed}>
          <div className="logo">logo</div>
          <Menu
            theme="dark"
            mode="inline"
            defaultSelectedKeys={["1"]}
            items={[
              {
                key: "1",
                icon: <UserOutlined />,
                label: <NavLink to="/vue-app">vue应用</NavLink>,
              },
              {
                key: "2",
                icon: <VideoCameraOutlined />,
                label: <NavLink to="/react-app">react应用</NavLink>,
              },
            ]}
          />
        </Sider>
        <Layout className="layout-main">
          <Header className="header">
            <Button
              type="text"
              icon={collapsed ? <MenuUnfoldOutlined /> : <MenuFoldOutlined />}
              onClick={() => setCollapsed(!collapsed)}
              className="collapse-btn"
            />
          </Header>
          <Content id="lyContainer" className="layout-content">
            Content
          </Content>
        </Layout>
      </Layout>
    </div>
  );
}

export default App;

修改App.css样式如下:

#root,
.App,
.layout-container {
  width: 100%;
  height: 100%;
}
.logo {
  height: 64px;
  line-height: 64px;
  color: #fff;
  text-align: center;
}
.layout-main {
  overflow-y: auto;
}
.header {
  padding: 0;
  background-color: #fff;
}
.header .collapse-btn {
  font-size: 16px;
  width: 64px;
}
.layout-content{
  padding: 24px;
}


效果如下:
在这里插入图片描述
二、react微应用

npx create-react-app react-qiankun-sub
cd react-qiankun-sub
npm start

修改index.html下的id
在这里插入图片描述
在src下新建public-path.js,将如下代码放进去

if (window.__POWERED_BY_QIANKUN__) {
  // eslint-disable-next-line no-undef
  __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}

安装react-router :

npm i react-router-dom

设置 history 模式路由的 base,并在index.js中导入public-path.js,修改index.js中代码如下:

import { BrowserRouter } from "react-router-dom";

import "./public-path";

let root = null;
function render(props) {
  const { container } = props;
  root =
    root ||
    ReactDOM.createRoot(
      container
        ? container.querySelector("#subRoot")
        : document.getElementById("subRoot")
    );
  root.render(
    <BrowserRouter
      basename={window.__POWERED_BY_QIANKUN__ ? "/react-app" : "/"}
    >
      <React.StrictMode>
        <App />
      </React.StrictMode>
    </BrowserRouter>
  );
}

if (!window.__POWERED_BY_QIANKUN__) {
  render({});
}

export async function bootstrap() {
  console.log("[react16] react app bootstraped");
}

export async function mount(props) {
  console.log("[react16] props from main framework", props);
  render(props);
}
// https://github.com/kobeyk/micro-app-react-template/blob/main/config-overrides.js
export async function unmount(props) {
  // const { container } = props;
  root.unmount();
  root = null;
}

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

修改webpack配置,安装craco:

npm i @craco/craco

根目录新增 craco.config.js,将如下代码放进去:

const { name } = require("./package");

module.exports = {
  webpack: {
    configure: (webpackConfig) => {
      webpackConfig.output.library = `${name}-[name]`;
      webpackConfig.output.libraryTarget = "umd";
      webpackConfig.output.chunkLoadingGlobal = `webpackJsonp_${name}`;
      return webpackConfig;
    },
  },
  devServer: (devServerConfig) => {
    devServerConfig.historyApiFallback = true;
    devServerConfig.open = false;
    devServerConfig.hot = false;
    devServerConfig.watchFiles = [];
    devServerConfig.headers = {
      "Access-Control-Allow-Origin": "*",
    };
    return devServerConfig;
  },
};

修改package.json里面启动的命令,因为安装了craco

 "scripts": {
    "start": "craco start",
    "build": "craco build",
    "test": "craco test",
    "eject": "react-scripts eject"
  },

在这里插入图片描述

三、vue3微应用

npm init vue@latest

在这里插入图片描述

cd vue-qiankun
npm install
npm run format
npm run dev

在这里插入图片描述
安装vite-plugin-qiankun:

npm i vite-plugin-qiankun

https://www.npmjs.com/package/vite-plugin-qiankun
在vite.config.js加入如下配置



import qiankun from 'vite-plugin-qiankun'

// https://vitejs.dev/config/
export default defineConfig({
  // 生产环境需要指定运行域名作为base
  // base: 'http://xxx.com/'
  plugins: [
    vue(),
    qiankun('vue-app', {
      //  'vue-app' 是子应用名,与主应用注册时保持一致
      useDevMode: true // 如果是在主应用中加载子应用vite,必须打开这个,否则vite加载不成功, 单独运行没影响
    })
  ],
  resolve: {
    alias: {
      '@': fileURLToPath(new URL('./src', import.meta.url))
    }
  },
  server: {
    port: '5173',
    cors: true,
    origin: 'http://localhost:5173',  // 子应用引入到主应用之后,子应用中的图片在主应用下加载不出来、找不到,需要将origin设置成子应用本地运行地址
  }
})

在main.js中修改代码,如下:

import './assets/main.css'

import { createApp } from 'vue'
import { createPinia } from 'pinia'

import App from './App.vue'
import routes from './router'

import { renderWithQiankun, qiankunWindow } from 'vite-plugin-qiankun/dist/helper'
import { createRouter, createWebHistory } from 'vue-router'

let router = null
let instance = null
let history = null

function render(props = {}) {
  const { container } = props
  history = createWebHistory(qiankunWindow.__POWERED_BY_QIANKUN__ ? '/vue-app' : '/')
  router = createRouter({
    history,
    routes
  })

  instance = createApp(App)
  instance.use(router)
  instance.use(createPinia())
  instance.mount(container ? container.querySelector('#app') : '#app')
  if (qiankunWindow.__POWERED_BY_QIANKUN__) {
    console.log('我正在作为子应用运行')
  }
}

// some code
renderWithQiankun({
  bootstrap() {
    console.log('bootstrap')
  },
  mount(props) {
    console.log('viteapp mount')
    render(props)
    // console.log(instance.config.globalProperties.$route,333);
  },
  unmount() {
    console.log('vite被卸载了')
    instance.unmount()
    instance._container.innerHTML = ''
    history.destroy() // 不卸载  router 会导致其他应用路由失败
    router = null
    instance = null
  }
})

if (!qiankunWindow.__POWERED_BY_QIANKUN__) {
  render()
}

效果如下:

在这里插入图片描述
在这里插入图片描述

问题:

  1. 应用间的样式隔离:
    在最新的 qiankun 版本中,你也可以尝试通过配置{ sandbox : { experimentalStyleIsolation: true } } 的方式开启运行时的 scoped css 功能,从而解决应用间的样式隔离问题

在主应用的index.js下的start中加入sandbox配置 ,代码如下:


start({ sandbox : { experimentalStyleIsolation: true }});

在这里插入图片描述

  1. 主应用中切换到子应用对应的页面,子应用空白,控制台也不报错
    元素检查看主应用中是否有子应用的元素,如果有,那可能是样式原因导致的

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【C++】将类对象转换成基本数据类型

2023年7月19日&#xff0c;周三晚上&#xff1a; 今天晚上看源码的时候&#xff0c;突然在某个类里面看到了“operator bool() const;”&#xff0c;我完全想不起来这是啥意思了&#xff0c;于是今晚重新学习了一下 目录 类型转换函数的定义类型转换函数的作用 类型转换函数的…

Redis(三)存储原理与数据模型(hash冲突、渐进式rehash)

Redis系列文章 Redis&#xff08;一&#xff09;原理及基本命令&#xff08;柔性数组&#xff09; Redis&#xff08;二&#xff09;网络协议和异步方式&#xff08;乐观锁&悲观锁&#xff09; Redis&#xff08;三&#xff09;存储原理与数据模型&#xff08;hash冲突、渐…

超牛逼黑客帝国代码雨,装X必用

html 1.用法 在电脑桌面新建一个文本文档&#xff0c;然后将代码复制到文本文档里&#xff0c;再将后缀改为".html"。 2.效果图 <!DOCTYPE html> <html> <head><title>黑客帝国代码雨</title> </head><body> <can…

C++编程(四) —— OOP

文章目录 前言一、this指针二、构造和析构三、深拷贝浅拷贝浅拷贝深拷贝 编程实践 前言 什么是OOP思想&#xff1f; OOP语言的四大特征&#xff1a; 抽象&#xff0c;封装/隐藏&#xff0c;继承&#xff0c;多态 一、this指针 this指针》类》很多对象 一套成员方法是如何处…

【矩阵的基本操作】——MatLab基础

目录索引 矩阵的基本操作&#xff1a;转置&#xff1a;矩阵的拼接&#xff1a;*横拼&#xff1a;**竖拼&#xff1a;* 矩阵的索引&#xff1a;取元素&#xff1a;*end():* 取区域&#xff1a;逻辑判断&#xff1a;逻辑取值&#xff1a;find()&#xff1a; 矩阵的基本操作&#…

51单片机学习--独立按键控制LED

功能&#xff1a;按下K1时D1亮&#xff0c;松开时D1灭&#xff0c;P3_1对应K1 , P2_0对应D1 #include <REGX52.H>void main() {while(1) {if(P3_1 0) //按下K1{P2_0 0;}else{P2_0 1;}}} 按下按钮和松开按钮时会有抖动&#xff0c;所以需要用延时函数来避免抖动造成的…

JDK、JRE与JVM三者之间的关系及区别

文章目录 0、关系1、JDK2、JRE3、JVM 0、关系 JDK JRE Java 开发工具包 [Java,Javac,Javadoc,Javap等]JRE JVM Java 的核心类库 1、JDK 什么是JDK&#xff0c;JDK是用于Java程序开发的最小环境&#xff0c;包含&#xff1a;Java程序设计语言&#xff0c;Java虚拟机&#…

【DC-DC】APS54083 降压恒流驱动器大功率深度调光 舞台 RGB 汽车照明 台灯驱动芯片

产品描述 APS54083 是一款 PWM 工作模式,高效率、外围简单、外置功率 MOS 管&#xff0c;适用于 5-220V 输入高精度降压 LED 恒流驱动芯片。输出最大功率150W最大电流 6A。APS54083 可实现线性调光和 PWM 调光&#xff0c;线性调光脚有效电压范围 0.5-2.5V.PWM 调光频率范围 1…

手把手教你搭建SpringCloud项目(十)集成Hystrix之服务降级

什么是微服务&#xff1f;一看就会系列&#xff01; 一、手把手教你搭建SpringCloud项目&#xff08;一&#xff09;图文详解&#xff0c;傻瓜式操作 二、手把手教你搭建SpringCloud项目&#xff08;二&#xff09;生产者与消费者 三、手把手教你搭建SpringCloud项目&#x…

网络 socket

文章目录 概念和 TCP、UDP 区别和 HTTP 区别 概念 为网络通信提供的接口&#xff0c;定义了应用程序如何访问网络资源、如何发送和接收数据等&#xff0c;Socket 是一个包含了IP地址和端口号的组合&#xff0c;当一个应用程序想要与另一个应用程序通信时&#xff0c;它会向特定…

【es】部署后打不开访问页面

具体报错&#xff1a; [2023-07-18T00:55:28,203][WARN ][o.e.x.s.t.n.SecurityNetty4HttpServerTransport] [demo] received plaintext http traffic on an https channel, closing connection Netty4HttpChannel{localAddress/127.0.0.1:9200, remoteAddress/127.0.0.1:5529…

微服务Day2——Nacos注册中心入门

Nacos注册中心 1、Nacos简介 国内公司一般都推崇阿里巴巴的技术&#xff0c;比如注册中心&#xff0c;SpringCloudAlibaba也推出了一个名为Nacos的注册中心。 2、Mac安装 进入Nacos官网下载安装包 http://nacos.io/zh-cn/ Github仓库地址 下载解压后进入nacos/bin目录下 …

【力扣每日一题】2023.7.19 模拟行走机器人

题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 机器人模拟类题目,力扣里有很多这样的模拟题,就是模拟机器人在坐标系上行走. 套路就是记下每个方向行走后,x轴和y轴的变化&#xff08;代码中的direction&#xff09;,例如 direction[0] 就表示向北走一次,y轴1,x轴不变.…

回归预测 | MATLAB实现基于KELM-Adaboost核极限学习机结合AdaBoost多输入单输出回归预测

回归预测 | MATLAB实现基于KELM-Adaboost核极限学习机结合AdaBoost多输入单输出回归预测 目录 回归预测 | MATLAB实现基于KELM-Adaboost核极限学习机结合AdaBoost多输入单输出回归预测预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介绍 1.MATLAB实现基于KELM-Adaboo…

【汉诺塔问题分析】

一、背景 汉诺塔问题是一种经典的递归问题&#xff0c;它由法国数学家Huygens在1665年发现&#xff0c;也是一道有趣的数学难题。这道问题的主要目的是将三根柱子上的一堆盘子移动到另一根柱子上&#xff0c;移动过程中每次只能移动一个盘子&#xff0c;并且大盘子不能放在小盘…

jmeter压测过程中,ServerAgent响应异常:Cannot send data to network connection

ServerAgent异常信息&#xff1a; Cannot send data to network connection&#xff08;无法将数据发送到网络连接&#xff09; 原因&#xff1a; linux 防火墙 拦截了当前端口 解决方案&#xff1a; Linux 执行以下命令 /sbin/iptables -I INPUT -p tcp --dport 4445 -j ACC…

被字节拷打了~基础还是太重要了...

今天分享一篇一位同学去字节面试的实习面经&#xff0c;技术栈是java&#xff0c;投了go后端岗位&#xff0c;主要拷打了 redismysql网络系统java算法&#xff0c;面试问题主要集中在 mysql、redis、网络这三部门&#xff0c;因为面试官是搞 go 的&#xff0c;java 只是随便问了…

Flink 启动就报错,但exception没提示。其中一个task failure 该怎么办?

文章目录 前言一、排查二、解决 前言 最近我在生产又遇到一个问题&#xff0c;就是消费着一段时间之后&#xff0c;忽然就不再消费了&#xff0c;但也不报错。观察了几次&#xff0c;我发现时间基本是停留在上下班高峰期数据量最大的时候。我主观猜测可能是同时间进来的数据过…

(学习笔记-TCP连接建立)TCP 为什么是三次握手?不是两次、四次?

常规回答&#xff1a;“因为三次握手才能保证双方具有接收和发送的能力” 原因一&#xff1a;避免历史连接 三次握手的首要原因是为了防止旧的重复连接初始化造成混乱。 假设&#xff1a;客户端先发送了SYN(seq90)报文&#xff0c;然后客户端宕机了&#xff0c;而且这个SYN报…

QGIS绘制一张地图——创建和编辑绘制线要素、由线要素生成面要素、面要素的编辑

前言 我们以描绘北京市市区案例来演示这部分功能。步骤大致如下: 1、按照市区分区的分界线来绘制线要素。 2、根据所绘线要素生成面要素。 3、对生成的面要素做整理编辑。待绘制底图如图所示: 一、创建和编辑绘制线要素 1.1 创建线要素 我们点击新建Shapefile要素按钮,…