首页 > 其他分享 >微前端之qiankun 分别引入两种子应用 -- react && vue + vite

微前端之qiankun 分别引入两种子应用 -- react && vue + vite

时间:2023-02-17 14:55:15浏览次数:40  
标签:qiankun -- app react && import config vite

搭建主应用

主应用不限技术栈,只需要提供一个容器 DOM,然后注册微应用并 start 即可。

1、下载项目

// TS
npx create-react-app qk-main --template typescript
// JS
npx create-react-app qk-mai

2、安装 qiankun

yarn add qiankun 或者 npm i qiankun -S

3、基于路由配置自动注册微应用

// src/index.tsx
// 引入配置函数
import { registerMicroApps, start } from "qiankun";

//配置两个子应用
registerMicroApps([
  {
    // 子应用名字
    name: "qk-micro-react",
    // 子应用容器id 需要在父应用中创建相关元素
    container: "#qk-micro-react",
    // 子应用进入地址
    entry: "http://localhost:3011",
    // 激活子应用的路由
    activeRule: "/qk-micro-react",
  },
  {
    name: "qk-micro-vue",
    container: "#qk-micro-vue",
    entry: "http://localhost:3012/",
    activeRule: "/qk-micro-vue",
  },
]);

//启动 qiankun
start({
  sandbox: {
    // 样式隔离特性
    experimentalStyleIsolation: true,
  },
});

代码预览

4、添加子应用对应的容器 (仔细看注释 这里比较容易出错嘞)

// App.tsx
import React from "react";
import "./App.css";
import { Link, BrowserRouter } from "react-router-dom";

function App() {
  return (
    <div className="App">
      {/* 先做一个简单的路由跳转 */}
      <BrowserRouter>
        <h3>
          <Link to="/qk-micro-react">微前端React</Link>
        </h3>
        <h3>
          <Link to="/qk-micro-vue">微前端Vue</Link>
        </h3>
      </BrowserRouter>
      {/* id 要与 registerMicroApps 当中的 container 对齐 */}
      {/* react子应用挂载容器 id=qk-micro-react */}
      <div id="qk-micro-react" />
      {/* vue子应用挂在容器 id=qk-micro-vue */}
      <div id="qk-micro-vue" />
    </div>
  );
}

export default App;

页面预览

搭建 react 子应用

第一步是增加 public-path.js  文件,用于修改运行时的  publicPath,修改 history 模式的路由,但是要区分独立运行和在 qiankun 中运行两种环境,在入口文件导出微应用的生命周期函数,最后修改  webpack  打包,允许开发环境跨域和  umd  打包

1、下载项目

// TS
npx create-react-app qk-main --template typescript
// JS
npx create-react-app qk-main

2、在 src 目录下面新增 public-path.ts

如果不添加 可能会出现静态资源无法加载的问题,子应用在微服务中打开 它默认使用了父应用的前缀,导致子应用无法加载自身的静态资源

if (window.__POWERED_BY_QIANKUN__) {
  // @ts-ignore
  __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}

export {};

3、导出生命周期函数,修改路由基础路径

如果对这几个生命周期函数不理解的 可以查阅 single-spa docs

// 入口文件 index.tsx
//引入新增的 public-path 文件
import "./public-path";
import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import App from "./App";
import reportWebVitals from "./reportWebVitals";
import { BrowserRouter } from "react-router-dom";

let root: ReactDOM.Root;

function createRoot(props: Record<string, any>) {
  // container中包含了qiankun创建的dom,它会插入一个带有id为root的dom
  const { container } = props;
  root = ReactDOM.createRoot(
    container
      ? container.querySelector("#root")
      : document.querySelector("#root")
  );
}
// 独立运行,直接调用 createRoot函数 render
if (!window.__POWERED_BY_QIANKUN__) {
  createRoot({});
  // @ts-ignore
  root.render(
    <BrowserRouter>
      <App />
    </BrowserRouter>
  );
}

// lifecycle => 初始化
export async function bootstrap(props: Record<string, any>) {
  console.log(props);
}

// lifecycle => 挂载
export async function mount(props: Record<string, any>) {
  createRoot(props);
  //qiankun环境中渲染
  root.render(
    <BrowserRouter
      // 对两种不同的环境分别给出不同的基础路径
      basename={window.__POWERED_BY_QIANKUN__ ? "/qk-micro-react" : "/"}
    >
      <App />
    </BrowserRouter>
  );
}

// lifecycle => 卸载
export async function unmount(_props: Record<string, any>) {
  root.unmount();
}
reportWebVitals();

4、修改 webpack 配置

需要借助 react-app-rewired 或 @rescripts/cli 插件来完成对 webpack 配置的修改,我会分两种方法来描述

方法一:
安装插件 @rescripts/cli,
yarn add @rescripts/cli 或 npm i -D @rescripts/cli

根目录新增 .rescriptsrc.js:

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

module.exports = {
  webpack: (config) => {
    config.output.library = `${name}-[name]`;
    config.output.libraryTarget = "umd";
    // config.output.jsonpFunction = `webpackJsonp_${name}`;
    config.output.globalObject = "window";

    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;
  },
};

修改 package.json 文件

"scripts": {
    "start": "rescripts start",
    "build": "rescripts build",
    "test": "rescripts test",
    "eject": "rescripts eject"
},

方法二:
安装插件 react-app-rewired
yarn add react-app-rewired 或 npm i -D react-app-rewired
根目录下新增 config-overrides.js 文件

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

module.exports = {
  webpack: (config) => {
    config.output.library = `${name}-[name]`;
    config.output.libraryTarget = "umd";
    // config.output.jsonpFunction = `webpackJsonp_${name}`;
    config.output.globalObject = "window";

    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;
  },
};

修改 package.json 文件

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

启动项目时指定 3011 端口 或者 根目录添加.ENV 文件指定 3011 启动端口
port=3011

项目独立运行时

项目在微服务中打开时

如果微服务中无法打开 仔细查阅前面的注册配置是否有问题

搭建 vue3 + vite 子应用

目前 qiankun 还没有兼容 vite,还需借助第三方插件 vite-plugin-qiankun 来实现

1、下载项目

自选配置,尽量带路由,方便后续验证
npm init vue@latest

2、vite.config.ts 中添加插件,修改路由配置

import { fileURLToPath, URL } from "node:url";

import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import qiankun from "vite-plugin-qiankun";

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    vue(),
    // 添加qiankun插件
    qiankun("qk-micro-vue", {
      useDevMode: true,
    }),
  ],
  resolve: {
    alias: {
      "@": fileURLToPath(new URL("./src", import.meta.url)),
    },
  },
  server: {
    port: 3012,
    // 如果出现图片资源无法加载 请加上跨域
    origin: "http://localhost:3012",
    cors: true,
  },
});

修改路由配置,分两种情况.
1、独立运行. 2、微服务中运行.

3. main.ts 文件添加生命周期

在 vite-plugin-qiankun 插件中导出 initQianKun 函数,在函数中定义生命周期函数。
再分别对独立运行和微前端中运行做出不同的渲染

指定 3012 端口启动项目
单独运行:

微前端环境中运行:

路由切换:

关于 experimentalStyleIsolation

官方文档中表明 experimentalStyleIsolation 只是实验性的样式隔离特性,神说要有光的这篇文章给出的例子易懂,建议阅读
当 experimentalStyleIsolation 被设置为 true 时,qiankun 会改写子应用所添加的样式为所有样式规则增加一个特殊的选择器规则来限定其影响范围,因此改写后的代码会表达类似为如下结构:

// 假设应用名是 react16
.app-main {
  font-size: 14px;
}

div[data-qiankun-react16] .app-main {
  font-size: 14px;
}

之前两个子应用的选择器规则都发生了改变,均加上了 data-qiankun = 'yourself app name'

总结

当应用在微前端中运行的时候,它的 window 会变成一个经过 Proxy 代理的对象

应用通过判断 window.__POWERED_BY_QIANKUN 的布尔值来确定运行的环境
这篇文章主要是给对 qiankun docs 阅读不明白的 jym 出的一个小 demo,特别是 vite 这一块,网上完整的文章不算太多,官网又不兼容 vite,但 vite 又是趋势。这种场景挺尴尬的,希望今年 qiankun 能对 vite 也做出点兼容性上的改变。

标签:qiankun,--,app,react,&&,import,config,vite
From: https://www.cnblogs.com/wp-leonard/p/17130106.html

相关文章

  • Zabbix“专家坐诊”第181期问答汇总
    问题一Q:大佬们,有没有基础的监控模板触发器分享下?A:你可以试一下乐维免费版(https://forum.lwops.cn/download ),里面基本的模板全齐。 问题二Q:orabbix监控查询SQL执......
  • 如何在不同分辨率下,等比例显示图片,即图片自适应分辨率。
    前言:用于展示生产线数据相关信息在车辆生产线的小屏幕上【西门子的,比1980*1080的要小一圈,比pad要大一圈,专门给生产线做的】展示数据。数据用的flex布局,很简单的解决了自......
  • 前端使用axios如何提交表单请求
    //使用FormData创建参数letformData=newFormData();formData.append("jsonData",JSON.stringify(reportOptions.request));formDat......
  • 前端常见面试题(二)CSS
    1、(布局)盒模型宽度计算offsetwidth=(内容宽度+内边距+边框),无外边距。100+10*2+1*2=122px 补充:如果让offsetwith=100px该如何做?添加box-sizing=border-box 2、(布......
  • JuiceFS 在火山引擎边缘计算的应用实践
    火山引擎边缘云是以云计算基础技术和边缘异构算力结合网络为基础,构建在边缘大规模基础设施之上的云计算服务,形成以边缘位置的计算、网络、存储、安全、智能为核心能力的新......
  • 建筑CAD中如何标注动态标高?CAD标注动态标高步骤
    在建筑CAD软件中,标高标注用来表示某个点的高程或者垂直高度。浩辰CAD建筑软件中以标高对象来实现CAD标高的标注,标高画法符合国家建筑制图统一标准与总图制图标准的图例,同时......
  • nacos安装
    nacos安装到nacos官网https://nacos.io/zh-cn/进入Github下拉页面,点击此处可以下载历史版本此处下载的是nacos-server-2.2.0.zip对文件进行解压,在终端执行解压完成后......
  • Vue CLI 2内置框架webpack框架结构解析
    目前Vue已经到3.X版本,相应的VueCLI也已经是VueCLI3版本,创建命令使用vuecreate,如果要用2.X版的vueinit命令,需要全局安装一个桥接工具:npminstall-g@vue/cli-init创......
  • odoo手动提交事务问题探索
    背景:在做项目时,发现数据库中几百条数据的修改时间都是相同的。寻找其中原因,在代码层面为了避免大数据量放在一次修改数据,特意做了分页查询,每一页执行一次更新方法,所有数据......
  • 建筑CAD软件导出图纸时如何默认保留墙基线?
    有些设计师在建筑CAD软件中绘制完成图纸后,想要在导出图纸的时候默认保留墙基线,但却不知道该如何设置,本节建筑CAD教程就和小编一起来了解一下浩辰CAD建筑软件中导出图纸时是......