通常来说,要在 umijs 中加载一个外部 qiankun 微应用,只需要在 .umirc 中配置好对应的 app,然后使用 umi 内置的 MicroApp 加载微应用即可。

但是我遇到一个比较特殊的场景,需要在一个 umi root 节点外的元素上加载一个微应用,这就导致无法直接使用 MicroApp,因为缺少了 umi 相关的 qiankun 环境。

针对这种情况,参考了 umi、qiankun 的官方文档,还有其他人的方案之后,决定直接使用 qiankun 的手动加载微应用的方式。

qiankun 提供了一个命令式加载微应用的方法 loadMicroApp,用在 react 组件内也比较方便,唯一的问题是,我们已经在 umi 中定义过外部微应用的相关配置了,在这里需要保持一致,因此利用 umi 的 getMasterOptions 获取当前 umi 配置,找到对应的微应用配置。

import React, { useEffect, useRef } from 'react'
import { loadMicroApp } from 'qiankun'
import { getMasterOptions } from 'umi'

export function ExternalApp(props) {
  const { } = props

  const app = useRef<any>()
  const containerRef = useRef<HTMLDivElement>()

  const loadApp = () => {
    const masterOptions = getMasterOptions()
    if (masterOptions && Array.isArray(masterOptions.apps)) {
      const targetApp = masterOptions.apps.find(config => config.name === 'targetApp')
      if (threenets) {
        app.current = loadMicroApp({
          ...targetApp,
          container: containerRef.current,
          props: {
            // some props
          },
        })
      }
    }
  }

  const unload = () => {
    if (app.current) {
      app.current.unmount()
    }
    app.current = null
  }

  useEffect(() => {
    loadApp()
    return () => {
      unload()
    }
  }, [])
  return <div ref={ref => { containerRef.current = ref }}></div>
}