使用qiankun搭建微前端应用及踩坑

线上演示地址:React App

源码地址:https://github.com/Jiang-K-J/micro-app?tab=readme-ov-file (帮忙点个小星星)

主应用:react 18+

子应用:vite + vue3

子应用:react 18+

安装

  1. 主应用
$ yarn add qiankun # 或者 npm i qiankun -S
  1. 子应用(如果你的子应用不是vite构建的,你无需安装任何插件)
npm i vite-plugin-qiankun

搭建

在主应用中注册子应用
import { registerMicroApps, start } from 'qiankun';

registerMicroApps([
  {
    name: 'react app', // 子应用的名称
    entry: '//localhost:7100', // 子应用运行的url和port
    container: '#yourContainer', // 用于放置子应用显示的载体
    activeRule: '/sub-react', // 匹配的路由
  },
  {
    name: 'vue app',
   entry: '//localhost:3000',
    container: '#yourContainer',
    activeRule: '/sub-vue',
  },
]);

start();
子应用配置
  • vite子应用
import { createApp } from 'vue'
import App from './App.vue'
import { renderWithQiankun, qiankunWindow } from 'vite-plugin-qiankun/dist/helper';
import { router, abstractRouter } from './router';
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'

let app;
if (!qiankunWindow.__POWERED_BY_QIANKUN__) {
  createApp(App).use(router).use(ElementPlus).mount('#app');
} else {
  renderWithQiankun({
    // 子应用挂载
    mount(props) {
      let routerInstance = null;
      console.log('props', props?.path);
      if (props?.path) {
        routerInstance = abstractRouter;
      } else {
        routerInstance = router;
      }
      app = createApp(App);
      // 使用 provide 将 props 传递给所有后代组件
      app.provide('qiankunProps', props); 
      app.use(routerInstance).use(ElementPlus);
      app.mount(props.container.querySelector('#app'));
      if (props?.path) {
        routerInstance.push(props.path)
      }
    },
    // 只有子应用第一次加载会触发
    bootstrap() {
      console.log('vue app bootstrap');
    },
    // 更新
    update() {
      console.log('vue app update');
    },
    // 卸载
    unmount() {
      console.log('vue app unmount');
      app?.unmount();
    }
  });
}
  • react子应用
import React from "react";
import { createRoot } from "react-dom/client";
import { BrowserRouter, MemoryRouter } from "react-router-dom";
import { QiankunContext } from "./QiankunContext.jsx";
import "./index.css";
import App from "./App";
import "./public-path";  // webpack子应用需要新增一个这样的文件,下方有说明
import "./a1.js";

let root;
function render(props) {
  const { container,path } = props;
  const RouterWrapper = props?.path ? MemoryRouter : BrowserRouter;
  const dom = container
    ? container.querySelector("#root")
    : document.getElementById("root");
  root = createRoot(dom);
  root.render(
    <RouterWrapper basename="/sub-react" initialEntries={path ? [path] : ["/"]}>
      <QiankunContext.Provider value={props}>
        <App mianProps={props} />
      </QiankunContext.Provider>
    </RouterWrapper>
  );
}

// 判断是否在qiankun环境下,非qiankun环境下独立运行
if (!window.__POWERED_BY_QIANKUN__) {
  render({});
}

// 各个生命周期
// bootstrap 只会在微应用初始化的时候调用一次,下次微应用重新进入时会直接调用 mount 钩子,不会再重复触发 bootstrap。
export async function bootstrap() {
  console.log("react app bootstraped");
}

// 应用每次进入都会调用 mount 方法,通常我们在这里触发应用的渲染方法
export async function mount(props) {
  console.log("props from main framework", props);
  render(props);
}

// 应用每次 切出/卸载 会调用的方法,通常在这里我们会卸载微应用的应用实例
export async function unmount(props) {
  root.unmount();
}

basename="/sub-react" 这个和你在主应用注册子应用中的activeRule要保持一直

webpack构建的子应用需要新增下面的文件,并在入口文件中进行导入

src 目录新增 public-path.js

if (window.__POWERED_BY_QIANKUN__) {
  __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}

子应用配置文件修改
  • webpack构建的应用

由于webpack构建的应用一般不会暴露webpack文件,我们这里可以下载 react-app-rewired 这个插件用于修改webpack配置,具体可以百度一下

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

module.exports = {
  webpack: (config) => {
    // 设置输出配置
    config.output.library = `${name}-[name]`;
    config.output.libraryTarget = "umd";
    config.output.chunkLoadingGlobal = `webpackJsonp_${name}`;

    return config;
  },
  devServer: (_) => {
    const config = _;

    config.headers = {
      "Access-Control-Allow-Origin": "*",
    };
    config.historyApiFallback = true;
    config.hot = false;
    config.watchContentBase = false;
    config.liveReload = false;

    return config;
  },
};
  • vite构建的应用
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import qiankun from 'vite-plugin-qiankun';
export default defineConfig({
  base: '/sub-vue', // 和基座中配置的activeRule一致
  server: {
    port: 3000,
    cors: true,
    origin: 'http://localhost:3000' //你的实际运行地址
  },
  plugins: [
    vue(),
    qiankun('sub-vue', { // 配置qiankun插件
      useDevMode: true
    }),
  ]
})
# 这里还需要配置下方那部分内容,具体怎样在vite中配置output,可以百度一下
  output: {
    library: `${name}-[name]`,
    libraryTarget: 'umd', // 把微应用打包成 umd 库格式
    jsonpFunction: `webpackJsonp_${name}`, // webpack 5 需要把 jsonpFunction 替换成 chunkLoadingGlobal
  },

具体配置可以参考官网文档:项目实践 - qiankun

建议:vite应用中base配置应该和实际线上地址保持一致,这样可以避免很多保持:

base: 'http://xxx:3000/sub-vue', // 和基座中配置的activeRule一致

部署

部署主要是nginx配置,没有别的操作

主应用

    location / {
      add_header Cache-Control no-cache;
      index index.html;
      try_files $uri /index.html;
    }

子应用

# /sub-react 这个需要和activeRule保持一致即可
 location /sub-react {
     # 设置允许的跨域来源
        alias /web/qiankun/rf; # 指向静态文件目录
        index index.html;
        try_files $uri /index.html; # 注意这里的路径,仅需指向子应用的 `index.html`
    }
    
    
    location / {
  
      # 添加跨域头
      add_header Access-Control-Allow-Origin *;
      add_header Access-Control-Allow-Methods "GET, POST, OPTIONS";
      add_header Access-Control-Allow-Headers "Content-Type, Authorization";
  
      if ($request_method = OPTIONS) {
          add_header Access-Control-Allow-Origin *;
          add_header Access-Control-Allow-Methods "GET, POST, OPTIONS";
          add_header Access-Control-Allow-Headers "Content-Type, Authorization";
          return 204;
      }
    }

踩坑汇总

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

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

相关文章

文献分享集:跨模态的最邻近查询RoarGraph

文章目录 1. \textbf{1. } 1. 导论 1.1. \textbf{1.1. } 1.1. 研究背景 1.2. \textbf{1.2. } 1.2. 本文的研究 1.3. \textbf{1.3. } 1.3. 有关工作 2. \textbf{2. } 2. 对 OOD \textbf{OOD} OOD负载的分析与验证 2.1. \textbf{2.1. } 2.1. 初步的背景及其验证 2.1.1. \textbf{2…

【读书笔记·VLSI电路设计方法解密】问题35:ASIC设计流程的两个主要方面是什么

毫无疑问,ASIC设计流程是一个复杂的系统,包含了许多商业CAD工具以及许多内部开发的工具或脚本。然而,无论流程中集成了多少工具或脚本,ASIC设计流程的核心目标始终可以归结为两个关键点:创建和检查。 创建过程指的是生成硬件的活动,例如RTL编码、逻辑综合以及布局布线。…

域上的多项式环,整除,相通,互质

例1.已知 (R,,x)为域&#xff0c;请选出正确的说法:(A)(R,,x)也是整区; ABCD (B)R中无零因子; C)R在x运算上满足第一、二、三指数律; (D)R只有平凡理想; (E)R只有平凡子环。 域的特征&#xff1a; 域中&#xff0c;非0元素的加法周期 思考、在模7整数环R,中&#xff0c;…

CSS3——3. 书写格式二

<!DOCTYPE html> <html><head><meta charset"UTF-8"><title></title></head><body><!--css书写&#xff1a;--><!--1. 属性名:属性值--><!--2.属性值是对属性的相关描述--><!--3.属性名必须是…

2街景两两对比程序,Trueskill计算评分代码,训练模型,预测街景

目录 0、Emeditor软件1、place pluse 2.0数据集2、街景主观感知两两对比程序3、Trueskill结果4、训练模型Resnet&#xff0c;Efficient&#xff0c;VIT等对比选择。5、模型预测6、其他数据处理/程序/指导&#xff01;&#xff01;&#xff01;优势&#xff1a;全网最全最细&am…

【React+TypeScript+DeepSeek】穿越时空对话机

引言 在这个数字化的时代&#xff0c;历史学习常常给人一种距离感。教科书中的历史人物似乎永远停留在文字里&#xff0c;我们无法真正理解他们的思想和智慧。如何让这些伟大的历史人物"活"起来&#xff1f;如何让历史学习变得生动有趣&#xff1f;带着这些思考&…

Golang学习历程【第五篇 复合数据类型:数组切片】

Golang学习历程【第五篇 复合数据类型&#xff1a;数组&切片】 1. 数组&#xff08;Array&#xff09;1.1 数组的定义1.2 初始化数组1.3 数据的循环遍历1.4 多维数组 2. 切片&#xff08;Slice&#xff09;2.1 切片声明、初始化2.2 基于数组创建切片2.2 切片的长度(len)和容…

ESP32自动下载电路分享

下面是一个ESP32系列或者ESP8266等电路的一个自动下载电路 在ESP32等模块需要烧写程序的时候&#xff0c;需要通过将EN引脚更改为低电平并将IO0引脚设置为低电平来切换到烧写模式。 有时候也会采用先将IO接到一个按键上&#xff0c;按住按键拉低IO0的同时重新上电的方式进入烧写…

【OceanBase】使用 Superset 连接 OceanBase 数据库并进行数据可视化分析

文章目录 前言一、前提条件二、操作步骤2.1 准备云主机实例2.2 安装docker-compose2.3 使用docker-compose安装Superset2.3.1 克隆 Superset 的 GitHub 存储库2.3.2 通过 Docker Compose 启动 Superset 2.4 开通 OB Cloud 云数据库2.5 获取连接串2.6 使用 Superset 连接 OceanB…

联发科MTK6771/MT6771安卓核心板规格参数介绍

MT6771&#xff0c;也被称为Helio P60&#xff0c;是联发科技(MediaTek)推出的一款中央处理器(CPU)芯片&#xff0c;可运行 android9.0 操作系统的 4G AI 安卓智能模块。MT6771芯片采用了12纳米工艺制造&#xff0c;拥有八个ARM Cortex-A73和Cortex-A53核心&#xff0c;主频分别…

修复 ITunes 在 Windows 或 Mac 上不断崩溃的问题 [100% 有效]

对于 iDevice 用户来说&#xff0c;只能通过 iTunes 在 iDevice 和计算机之间传输文件的困境一直是一个紧迫的问题。所有 iPhone 用户可能都知道&#xff0c;iTunes 并不是一款高效的应用程序&#xff0c;有时性能会很差&#xff0c;例如在 iDevices 和计算机之间传输文件时不断…

【AI大模型】深入GPT-2模型细节:揭秘其卓越性能的秘密

目录 &#x1f354; GPT2的架构 &#x1f354; GPT2模型的细节 2.1 模型过程 2.2 GPT2工作细节探究 &#x1f354; 小结 学习目标 掌握GPT2的架构掌握GPT2的训练任务和模型细节 &#x1f354; GPT2的架构 从模型架构上看, GPT2并没有特别新颖的架构, 它和只带有解码器模块…

C语言 - 理解函数栈帧

一&#xff1a;概述 函数栈帧是函数调用过程中为管理和存储函数相关信息&#xff08;如局部变量、返回地址等&#xff09;而在栈上分配的一块内存区域。它是实现函数调用、递归和返回的关键机制。 二&#xff1a;栈帧的组成 一个典型的栈帧通常包含以下内容&#xff08;从高地…

windows终端conda activate命令行不显示环境名

问题&#xff1a; 始终不显示环境名 解决 首先需要配置conda的环境变量 确保conda --version能显示版本 然后对cmd进行初始化&#xff0c;如果用的是vscode中的终端&#xff0c;那需要对powershell进行初始化 Windows CMD conda init cmd.exeWindows PowerShell conda …

检索增强生成 和思维链 结合: 如何创建检索增强思维链 (RAT)?

论文地址&#xff1a;https://arxiv.org/pdf/2403.05313 Github地址&#xff1a;https://github.com/CraftJarvis/RAT 想象一下&#xff0c;一个人工智能助手可以像莎士比亚一样写作&#xff0c;像专家一样推理。这听起来很了不起&#xff0c;对吧&#xff1f;但是&#xff0…

Fabric链码部署测试

参考链接&#xff1a;运行 Fabric 应用程序 — Hyperledger Fabric Docs 主文档 (hyperledger-fabric.readthedocs.io) &#xff08;2&#xff09;fabric2.4.3部署运行自己的链码 - 知乎 (zhihu.com) Fabric2.0测试网络部署链码 - 辉哥哥~ - 博客园 (cnblogs.com) 1.启动测试…

如何单独安装 MATLAB 工具箱

很多时候由于 MATLAB 太大而选择安装一些 Toolbox&#xff0c;但用着用着发现要用到某个没有安装的 Toolbox&#xff0c;这时候就需要再单独安装这个 Toolbox&#xff0c;下面提供两种方法。 本文以安装 系统辨识工具箱 System Identification Toolbox 为例。 方法一&#xf…

Anaconda/Pytorch/PyCharm/Jupyter安装及使用

1.ANACONDA安装 Anaconda 是全球领先的数据科学与机器学习平台&#xff0c;专为开发者、数据分析师设计。通过 Anaconda&#xff0c;您可以轻松管理数据环境、安装依赖包&#xff0c;快速启动数据分析、机器学习项目。 丰富的 Python 数据科学库&#xff1a;Anaconda 集成了常…

RocketMQ消费者如何消费消息以及ack

1.前言 此文章是在儒猿课程中的学习笔记&#xff0c;感兴趣的想看原来的课程可以去咨询儒猿课堂 这篇文章紧挨着上一篇博客来进行编写&#xff0c;有些不清楚的可以看下上一篇博客&#xff1a; https://blog.csdn.net/u013127325/article/details/144934073 2.broker是如何…

【Logstash02】企业级日志分析系统ELK之Logstash 输入 Input 插件

Logstash 使用 Logstash 命令 官方文档 https://www.elastic.co/guide/en/logstash/current/first-event.html #各种插件 https://www.elastic.co/guide/en/logstash/current/input-plugins.html https://www.elastic.co/guide/en/logstash/current/filter-plugins.html htt…