【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. 子应用需要在mountunmount去找到应用的挂在点和应用的卸载点
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-maxumi-simple-appumi-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路由
  • 路由路径要同一(因为子应用需要基座应用注入的路由去进行匹配)
相关推荐
zqx_729 分钟前
随记 前端框架React的初步认识
前端·react.js·前端框架
惜.己1 小时前
javaScript基础(8个案例+代码+效果图)
开发语言·前端·javascript·vscode·css3·html5
什么鬼昵称1 小时前
Pikachu-csrf-CSRF(get)
前端·csrf
长天一色1 小时前
【ECMAScript 从入门到进阶教程】第三部分:高级主题(高级函数与范式,元编程,正则表达式,性能优化)
服务器·开发语言·前端·javascript·性能优化·ecmascript
NiNg_1_2342 小时前
npm、yarn、pnpm之间的区别
前端·npm·node.js
秋殇与星河2 小时前
CSS总结
前端·css
BigYe程普2 小时前
我开发了一个出海全栈SaaS工具,还写了一套全栈开发教程
开发语言·前端·chrome·chatgpt·reactjs·个人开发
余生H2 小时前
前端的全栈混合之路Meteor篇:关于前后端分离及与各框架的对比
前端·javascript·node.js·全栈
程序员-珍2 小时前
使用openapi生成前端请求文件报错 ‘Token “Integer“ does not exist.‘
java·前端·spring boot·后端·restful·个人开发
axihaihai3 小时前
网站开发的发展(后端路由/前后端分离/前端路由)
前端