• 微前端(qiankun)主应用共享React组件


    前言

    最近需要重构一个老项目,定的方案用微前端去改造。主应用是老的项目,微应用是新的项目,由于重构时间比较紧张,子应用还需要使用父应用的一些组件。过程中遇到一些问题,记录一下。

    方案

    我们知道qiankun,可以通过props通信传递数据,把组件通过props传递过去不就行了。来开始改造我们的代码

    主应用

    导入组件,通过props共享出去

    import { registerMicroApps, start, setDefaultMountApp } from 'qiankun';
    
    // 导入一些组件 
    import Custom_Date from "@date/config";
    import CompanyTitle from '@title/config';
    import CustomSelect from '@select/config';
    import UpdateTime from '@updateTime/config';
    
    const shareComponent = {
        Custom_Date,
        CompanyTitle,
        CustomSelect,
        UpdateTime
    }
    
    registerMicroApps([
      {
        name: 'child-app', // 一级市场
        entry: '//localhost:7011',
        container: '#childApp',
        activeRule: '/page/appPM',
        props: {
          base: '/page/app-child/',
          ...shareComponent
        },
      },
    
    ]);
    
    

    子应用

    在qiankun的生命周期函数接收props,并缓存。

    缓存组件工具函数

    let shareMainComponent: Record<string, any> = {}
    
    // 获取共享的组件
    export const getShareMainComponent = () => {
      return shareMainComponent;
    }
    
    // 设置共享的组件
    export const setShareMainComponent = (currShareMainComponent: Record<string, any>) => {
      for (const key in currShareMainApp) {
        if (Object.prototype.hasOwnProperty.call(currShareMainComponent, key)) {
          shareMainComponent[key] = currShareMainComponent[key];
        }
      }
    }
    
    

    子应用生命周期中设置共享组件

    import { setShareMainComponent } from './utils/shareMainComponent';
    export const qiankun = {
    
      async bootstrap(props: any) {
        console.log('app1 bootstrap', props);
      },
      // 应用 render 之前触发
      async mount(props: any) {
        setShareMainComponent(props.shareMainApp);
      },
      async unmount(props: any) {
        console.log('app1 unmount', props);
      },
    };
    
    

    子应用使用

    import React, { FC, useEffect, useState } from 'react';
    import { getShareMainComponent } from '../../../utils/shareMain';
    
    export interface IndexConfigPageProps {
    }
    
    const IndexConfigPage: FC<IndexConfigPageProps> = props => {
        const {
          Custom_Date,
          CompanyTitle,
          CustomSelect,
          UpdateTime
        } = getShareMainComponent();
    
        useEffect(() => {
        }, []);
    
    
        return (
            <div>
                <Custom_Date />
                <CustomTitle />
            </div>
        );
    }
    
    export default IndexConfigPage;
    
    

    hooks组件问题

    类组件正常是没问题的,但hooks组件会有问题,报错如下

    image.png
    经排查分析,应该是React不是一个实例,hooks组件需要同一个实例。

    解决方案

    借助webpack的externals去用同一份React。

    主应用

    主应用入口index.html引入react和react-dom的js文件

    <script src="<%= htmlWebpackPlugin.files.publicPath %>public/react/react.development.js"></script>
    <script src="<%= htmlWebpackPlugin.files.publicPath %>public/react-dom/react-dom.development.js"></script>
    

    配置webpack的externals,如下

    externals: {
        'react': 'React',
        'react-dom': 'ReactDOM'
    },
    

    主应用设置完成,下面开始配置子应用。

    子应用

    子应用这时就不需要引入相关的js文件,直接配置externals,用主应用的React和ReactDom。配置如下

      externals: {
        'react': 'React',
        'react-dom': 'ReactDOM',
      },
    

    在此访问,问题得已解决

    结束语

    我们在重构巨石老项目的时候,可以考虑微前端,用微前端(qiankun)共享组件的时候,可以使用该方案。

    如果你觉得该文章不错,不妨

    1、点赞,让更多的人也能看到这篇内容

    2、关注我,让我们成为长期关系

    3、关注公众号「前端有话说」,里面已有多篇原创文章,和开发工具,欢迎各位的关注,第一时间阅读我的文章

  • 相关阅读:
    问chatgpt最近生活的困难
    [汇编实操]DOSBox工具安装——Ubuntu18.04系统
    玄机-第一章 应急响应- Linux入侵排查
    Git使用
    SQL的约束(下)
    用深度强化学习来玩Chrome小恐龙快跑
    超详细的 pytest 教程(一)使用入门篇
    电脑重置 Win 10系统
    为什么机加工行业需要建设生产运营管理系统
    Vue项目路由加前缀
  • 原文地址:https://www.cnblogs.com/qiaojie/p/16356285.html