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

news2024/12/26 14:01:03

一:主应用
搭建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. 主应用中切换到子应用对应的页面,子应用空白,控制台也不报错
    元素检查看主应用中是否有子应用的元素,如果有,那可能是样式原因导致的

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

心电前置放大电路制作与原理详细分析(附电路板实物图)

1、软件平台:Multisim仿真软件、EDA原理图绘制软件、医学电子学开发平台 2、硬件平台:心电示教仪、示波器、信号发生器、除颤仪、电烙铁 3、元件清单: 实验电路图 1、心电放大器原理图 2、50Hz双T陷波滤波器原理图 原理解释与计算 (1)一级放大电路 一级放大电路由…

【PCB专题】如何在Allegro中定义字体及批量修改丝印

在PCB板上丝印往往包含了很多信息,比如元件边界、元件参数、元件编号、极性、静电标识、板号等,这些信息在生产、测试及后期维护等都需要使用。一个好的设计往往都能从丝印的布局、丝印的完整性上体现出来。如下所示PCB在电解电容旁有极性丝印、电阻旁有电阻的位号信息等。 …

前端 | (七)浮动 | 尚硅谷前端html+css零基础教程2023最新

学习来源&#xff1a;尚硅谷前端htmlcss零基础教程&#xff0c;2023最新前端开发html5css3视频 文章目录 &#x1f4da;浮动介绍&#x1f407;元素浮动后的特点&#x1f407;浮动小练习&#x1f525;盒子1右浮动&#x1f525;盒子1左浮动&#x1f525;所有盒子都浮动&#x1f5…

EasyCVR视频融合平台能正常播放其他协议流,但无法播放HLS流的原因排查

EasyCVR基于云边端一体化架构&#xff0c;支持海量视频汇聚管理&#xff0c;平台支持多协议与多类型设备接入&#xff0c;具体包括国标GB28181、RTMP、RTSP/Onvif、海康Ehome、海康SDK、大华SDK、宇视SDK等&#xff0c;能对外分发RTMP、RTSP、HTTP-FLV、WS-FLV、HLS、WebRTC等。…

【Spring Boot】拦截器与统一功能处理:统一登录验证、统一异常处理与统一数据返回格式

前言 Spring AOP是一个基于面向切面编程的框架&#xff0c;用于将横切性关注点&#xff08;如日志记录、事务管理&#xff09;与业务逻辑分离&#xff0c;通过代理对象将这些关注点织入到目标对象的方法执行前后、抛出异常或返回结果时等特定位置执行&#xff0c;从而提高程序的…

浏览器显示ERR_NETWORK_ACCESS_DENIED,安全设置或防火墙可能正在阻止连接,无法上网

环境: Win10 专业版 HP台式机 问题描述: 浏览器显示ERR_NETWORK_ACCESS_DENIED,安全设置或防火墙可能正在阻止连接,无法上网 1.无线连接状态正常 打不开网站 2.可以ping通百度DNS解析正常 3.防火墙已关闭 这样的错误可能由于多种原因而发生 原因分析 1.防火墙/防…

ETHERCAT转ETHERCAT网关西门子为什么不支持ethercat两个ETHERCAT设备互联

1.1 产品功能 远创智控YC-ECT-ECT是自主研发的一款ETHERCAT从站功能的通讯网关。该产品主要功能是将2个ETHERCAT网络连接起来。 本网关连接到ETHERCAT总线中做为从站使用。 1.2 技术参数 1.2.1 远创智控YC-ECT-ECT技术参数 ● 网关做为ETHERCAT网络的从站&#xff0c;可以连接…

【Linux】内存使用相关

free 命令 查看内存大小 free -g :G单位 free -h : 可读性较高较理解 free -m : MB单位 total: 总内存used: 正在运行的进程使用的内存(used total – free – buff/cache)free: 未使用的内存 (free total – used – buff/cache)shared: 多个进程共享的内存buffers: 内存保留…

promise规范及应用(进阶)

##promise解析 *啥是异步? //异步执行let count 1let timer setTimeout(function () {countconsole.log(in, count);}, 1000);console.log(out);// out>1000>in//循环执行let count 1let timer setInterval(function () {countconsole.log(in, count);}, 1000);con…

isaac sim添加孔网格

isaac sim仿真和其它仿真实际上一样&#xff0c;对于孔的仿真&#xff0c;是没那么简单的 在此记录一下踩过的坑 1&#xff0c;首先&#xff0c;你需要在soildworks中将你的孔画出来&#xff0c;并导出stl 2&#xff0c;你可以在win10中使用3D画图查看孔的网格&#xff0c;看…

代码随想录算法训练营day7 | 454. 四数相加 II,383. 赎金信,15. 三数之和,18. 四数之和

目录 454. 四数相加 II 383. 赎金信 15. 三数之和 18. 四数之和 454. 四数相加 II 难度&#xff1a;medium 类型&#xff1a;哈希表 思路&#xff1a; 本题是使用哈希法的经典题目&#xff0c;而0015.三数之和 (opens new window)&#xff0c;0018.四数之和 (opens new …

迁移 Gitee 仓库到 Github

Step1: 在Gitee找到你要迁移的仓库, 并复制 克隆|下载 链接 Step2: 打开 Github, 找到 按钮选择 Import Step3: 打开 Github, 找到 按钮选择 Import Step4: Waiting... 等待导入成功 Over~ 还有一种镜像更新的方案, Gitee 支持镜像同步, 但是我使用时无法获取到仓库名,…

开源的短视频生成和编辑工具 Open Chat Video Editor

GitHub - SCUTlihaoyu/open-chat-video-editor: Open source short video automatic generation tool

MySQL的四种主要存储引擎

目录 目录 目录 &#xff08;一&#xff09;MyISAM &#xff08;二&#xff09;InnoDB 1)自动增长列&#xff1a; 2)外键约束&#xff1a; &#xff08;三&#xff09;MEMORY &#xff08;四&#xff09;MERGE 什么是存储引擎&#xff1f; 对MySQL来说&#xff0c;它…

系列七、VMware中的CentOS服务不息屏

一、场景 VMware中安装好CentOS7等虚拟机后&#xff0c;过一段时间会自动息屏&#xff0c;这个时候如果想执行操作&#xff0c;需要重新输入 用户名/密码&#xff0c;体验感不好。 二、解决方法 应用程序》系统工具》设置》Privacy》锁屏》自动锁屏&#xff08;关闭&#xff0…

Windows11 C盘瘦身

1.符号链接 将大文件夹移动到其他盘&#xff0c;创建成符号链接 2.修改Android Studio路径设置 1.SDK路径 2.Gradle路径 3.模拟器路径 设置环境变量 ANDROID_SDK_HOME

GRE和MGRE

目录 GRE GRE环境的搭建 MGRE MGRE的配置 MGRE环境下的RIP网络 MGRE实验 VPN 说到GRE&#xff0c;我们先来说个大家熟悉一点的&#xff0c;那就是VPN技术。 背景需求 企业、组织、商家等对专用网有强大的需求。 高性能、高速度和高安全性是专用网明显的优势。 物理专…

【数据结构】时间复杂度---OJ练习题

目录 &#x1f334;时间复杂度练习 &#x1f4cc;面试题--->消失的数字 题目描述 题目链接 &#x1f334;解题思路 &#x1f4cc;思路1&#xff1a; malloc函数用法 &#x1f4cc;思路2&#xff1a; &#x1f4cc;思路3&#xff1a; &#x1f334;时间复杂度练习 &…

具有吸引子的非线性系统(MatlabSimulink实现)

目录 &#x1f4a5;1 概述 &#x1f4da;2 运行结果 &#x1f389;3 参考文献 &#x1f308;4 Matlab代码&Simulink仿真实现 &#x1f4a5;1 概述 要在Simulink中实现具有吸引子的非线性系统&#xff0c;可以按照以下步骤进行操作&#xff1a; 1. 打开Simulink并创建一个…

Nginx基础(复习理论篇)

一、Nginx基本概念 1、Nginx是什么 Nginx是一个高性能的Http和反向代理服务器&#xff0c;其特点是占有内存少&#xff0c;并发能力强&#xff0c;事实上Nginx的并发能力确实在同类型的网页服务器中表现较好。 Nginx专为性能优化而开发&#xff0c;性能是其最重要的考量&…