qiankun配置父子应用及挂载问题

这两天研究了下qiankun这个微前端实现,正好写了两个项目用的是umi且是父子应用关系,之前的方式是在主应用添加iframe将子应用引进来,现在想通过改造成qiankun来将两个应用联系起来,顺便试试这个库。

事先说明父应用umi版本为2.9.0,子应用umi版本为2.10.0

具体操作是父子应用均通过yarn add @umijs/plugin-qiankun添加qiankun插件,父应用.umirc.ts添加如下:

const config:IConfig = {
  ...,
  routes: [
    ...,
    {
      path, '/app' // 这里是子应用的路由
    }
  ],
  plugins: [
    ...,
    [
      '@umijs/plugin-qiankun',
      {
        master: {
          apps: [
            {
              name: 'app',
              entry: '//localhost:9090',
              base: '/app',
              history: 'browser',
              mountElementId: 'root-slave',  // 注意这里是子应用要挂载在父应用上的节点id
            }
          ],
          jsSandBox: true,
          prefetch: true,
        }
      }
    ]
  ],
  proxy: {} // 如果是开发模式记得配置代理调用子应用服务端
}

配置完成后可以来到根组件下例如layout/index.tsx<div>{props.children}<div id='root-slave'></div></div>,其中root-slave的div就是子应用将要挂载的节点,这点很关键,如果没有的话将会提示Uncaught (in promise) Error: Target container is not a DOM element.之类的报错,还有一种方式是新建一个子应用组件,例如pages/subAppContainer.tsx组件,然后:

import React from 'react';
export default () => {
  return (
    <div id='root-slave'></div>
  )
}

这个时候.umirc.ts中routes里面应该添加component

{
  path: '/app', component: './subAppContainer'
}

配置app.ts,添加子应用生命周期函数:

export const qiankun = new Promise(resolve => {
  resolve({
    lifeCycles: {
      beforeLoad: props => {
        console.log('beforeLoad:', props);
      },
      beforeMount: props => {
        console.log('beforeMont:', props);
      },
      afterMount: props => {
        console.log('afterMount:', props);
      },
      beforeUnmount: props => {
        console.log('beforeUnmount:', props);
      },
      afterUnmount: props => {
        console.log('afterUmount:', props);
      },
    },
  });
});

至此主应用就配置的差不多了,接下来配置子应用

添加pages/document.ejs将根节点id修改为app-slave或者其他啥名字,配置.umirc.js

export default {
  ...,
  plugins: [
    ...,
    [
      '@umijs/plugin-qiankun/slave',
      {
        // 如果有其他配置请参照https://github.com/umijs/umi-plugin-qiankun里面进行配置
      },
      base: '/app',
      mountElementId: 'app-slave' // 与`document.ejs`的根节点id保持一致
    ]
  ]
}

此前子应用的服务端前缀为/api,为了避免与主应用冲突,将子应用服务端前缀改为/app/api
如此此次改造基本完成,过程中碰到的最大问题就是子应用的挂载问题,如果碰到其他问题也可以去umi的仓库提issue。

猜你喜欢

转载自www.cnblogs.com/musiq66/p/12635215.html