【qiankun接入教程】umi项目与非umi项目接入

简介

qiankun 是一个基于 single-spa 的微前端实现库,旨在帮助大家能更简单、无痛的构建一个生产可用微前端架构系统。

什么是微前端(官网抄的)

微前端架构具备以下几个核心价值:

技术栈无关 主框架不限制接入应用的技术栈,微应用具备完全自主权

独立开发、独立部署 微应用仓库独立,前后端可独立开发,部署完成后主框架自动完成同步更新

增量升级

在面对各种复杂场景时,我们通常很难对一个已经存在的系统做全量的技术栈升级或重构,而微前端是一种非常好的实施渐进式重构的手段和策略

独立运行时 每个微应用之间状态隔离,运行时状态不共享

微前端架构旨在解决单体应用在一个相对长的时间跨度下,由于参与的人员、团队的增多、变迁,从一个普通应用演变成一个巨石应用( Frontend Monolith)后,随之而来的应用不可维护的问题。这类问题在企业级 Web 应用中尤其常见。

qiankun接入核心

  1. 基座应用与子应用都需要安装qiankun依赖
  2. 基座应用注册子应用
  3. 子应用修改打包输出为umd、同时解决dev环境跨域问题(cors方案,可参考qiankun官方文档)
javascript 复制代码
const { name } = require('./package');
module.exports = {
devServer: {
  headers: {
    'Access-Control-Allow-Origin': '*',
  },
},
configureWebpack: {
  output: {
    library: `${name}-[name]`,
    libraryTarget: 'umd', // 把微应用打包成 umd 库格式
    jsonpFunction: `webpackJsonp_${name}`, // webpack 5 需要把 jsonpFunction 替换成 chunkLoadingGlobal
  },
},
};
  1. 子应用暴露qiankun生命周期钩子

接入场景与接入流程

接入场景主要分为umi项目和非umi项目,原因是因为umi提供了@umijs/plugin-qiankun插件一键开启微前端。

场景一

  • 基座应用与子应用都非umi项目

接入流程

  1. 主子应用安装qiankun依赖
  2. 主应用在项目入口文件中注入子应用
js 复制代码
import {registerMicroApps, start} from 'qiankun';

registerMicroApps([{
  name: 'child', // app name registered
  entry: '//localhost:8080', //子应用项目入口地址
  container: '#container',    //微前端挂在节点
  activeRule: '/',            //匹配路由
  props: {                    //初始化通信数据
    eventName: "TransferValue",
  }
}]);
start();   //开启qiankun
  1. 子应用入口文件暴露qiankun生命周期钩子函数
js 复制代码
export async function bootstrap() {
  console.log(' react app bootstraped');
}

export async function mount(props) {
}

export async function unmount(props) {
}
  1. 子应用需要在mount和unmount去找到应用的挂在点和应用的卸载点
js 复制代码
function render(props) {
  const {container} = props;
  ReactDOM.render(<App/>, container ? container.querySelector('#root') : document.querySelector('#root'));
}

if (!window.__POWERED_BY_QIANKUN__) {
  render({});
}               //判断应用是否为qiankun挂在

export async function mount(props) {
  console.log(props)
  render(props);
}

export async function unmount(props) {
  const {container} = props;
  ReactDOM.unmountComponentAtNode(container ? container.querySelector('#root') : document.querySelector('#root'));
}
  1. 修改webpack(vite同理)打包配置,以下以create-react-app脚手架项目为例;安装react-app-rewired 依赖,然后在项目目录下新建config-overrides.js文件,配置打包,修改启动脚本。

6. 完成接入

场景二

  • 基座应用非umi项目
  • 子应用umi4

接入流程

  1. 基座应用接入流程不变
  2. 子应用umi4分为umi-max和umi-simple-app 以umi-simple-app子应用接入为例
  3. umi-simple-app安装umi插件集@umijs/plugins
  4. 在umi配置文件中开启qiankkun插件并且开启子应用qiankun配置
js 复制代码
export default defineConfig({
  plugins: ["@umijs/plugins/dist/qiankun"],
  qiankun:{
    slave:{}
  },
});
  1. 在app.js文件中开启qiankun生命周期
js 复制代码
export const qiankun = {
    // 应用加载之前
    async bootstrap(props: any) {
        console.log('app2 bootstrap', props);
    },
    // 应用 render 之前触发
    async mount(props: any) {
        console.log('app2 mount', props);
    },
    // 应用卸载之后触发
    async unmount(props: any) {
        console.log('app2 unmount', props);
    },
};
  1. 接入完成(umi-max内部集成qiankun插件、直接启动qiankun配置、暴漏出qiankun生命周期钩子即可)

场景三

  • 基座应用与子应用都是umi4

接入流程

  1. 基座应用和子应用同时安装@umijs/plugins,在umi配置文件中开启qiankun插件配置
js 复制代码
 plugins: ["@umijs/plugins/dist/qiankun"]

umi-max跳过此步骤、umi-max集成了此插件

  1. 基座应用开启qiankun配置
js 复制代码
   qiankun: {
        master: {
            apps: [
                {
                    name: "child1",
                    entry: "//localhost:3010"
                },
            ]
        }
    }
  1. 基座应用注入路由使用microApp匹配子应用
js 复制代码
 routes: [{path: "/child1", microApp: "child1"}]

基座应用配置完毕

  1. 子应用开启qiankun配置、并注入路由
js 复制代码
export default defineConfig({
  plugins: ["@umijs/plugins/dist/qiankun"],
  qiankun:{
    slave:{}
  },
  base:"/child2",
  routes: [
    { path: "/", component: "index" },
  ],
  npmClient: 'pnpm',
});
  1. 在app.js入口文件中暴漏qiankun生命周期
js 复制代码
export const qiankun = {
    // 应用加载之前
    async bootstrap(props: any) {
        console.log('app2 bootstrap', props);
    },
    // 应用 render 之前触发
    async mount(props: any) {
        console.log('app2 mount', props);
    },
    // 应用卸载之后触发
    async unmount(props: any) {
        console.log('app2 unmount', props);
    },
};
  1. 接入流程完毕

小结

  • qiankun的使用场景主要分为umi项目或者非umi项目
  • umi项目无论基座应用还是子应用都可以使用umi自动封装的插件快速开启微前端配置
  • 非umi无论基座应用还是子应用都可以根据qiankun官方文档开启微前端配置
  • 基座应用和子应用可根据上面场景灵活搭配

通信

基座应用在app.js中暴漏出的useQiankunStateForSlave函数

js 复制代码
export function useQiankunStateForSlave() {
  const [globalState, setGlobalState] = useState<any>({
    slogan: 'Hello MicroFrontend',
  });

  return {
    globalState,
    setGlobalState,
  };
}

子应用在需要使用的地方直接通过以下使用

js 复制代码
const masterProps = useModel('@@qiankunStateFromMaster');

子应用打包成静态资源引入场景场景

在qiankun的文档中entry支持配置成对象,html一定是html字符串,script可以配置为需要注入的脚本地址 如以下所示:

js 复制代码
fetch('http://localhost:7001/dist/index.html') // 配置静态资源地址
  .then(response => response.text())
  .then(htmlString => {
    console.log(htmlString)
    registerMicroApps([{
      name: 'qiankun', // app name registered
      entry: {
        html: htmlString,
        scripts: ["http://localhost:7001/dist/umi.js", "http://localhost:7001/dist/p__index.async.js"] //需要注入的脚本地址
      },
      container: '#root-subapp-container', activeRule: '/test',
    }]);
    start();
  })
  .catch(error => {
    console.error('Error fetching the HTML file:', error);
  });

注意

  • 基座应用与子应用路由的模式需要同一,比如基座应用是hash路由,子应用也需要配置hash路由
  • 路由路径要同一(因为子应用需要基座应用注入的路由去进行匹配)
相关推荐
卸任7 小时前
Vibe coding工具使用心得
前端·ai编程
brien98 小时前
为什么模型标称 1M,Google Antigravity 聊到 256K 却突然失忆?我们给它做了个原生行内监控圆环
前端
修炼的dance8 小时前
录屏关键帧间隔多少合适?六档实测,2秒到10秒小了75.6%
前端
Lank_M8 小时前
关键帧从1秒拉到10秒,录屏小87.3%,摄像头小10.8%
前端
补码缩写8 小时前
用 ffprobe 拆录屏,八成字节在 29 个关键帧上
前端
百思不得小李8 小时前
一个复杂的动态表单是如何实现的
前端·设计模式
陈随易9 小时前
Cmder 停更 17 个月,2.0 支持 Windows Terminal
前端·后端·程序员
风骏时光牛马9 小时前
前沿视界
前端
kyriewen9 小时前
我扫了 814 个依赖,97 个还敢要 Node 10
前端·javascript·程序员
陈随易9 小时前
3000 万人在用的翻译插件,重写一遍就是一门生意
前端·后端·程序员