Umi (@umi/max) 微前端实战:Qiankun 插件从主子应用配置到通信、生命周期与错误处理的完整指南
2026/9/14 18:48:18 网站建设 项目流程

Umi (@umi/max) 微前端实战:Qiankun 插件从主子应用配置到通信、生命周期与错误处理的完整指南

【免费下载链接】umiA framework in react community ✨项目地址: https://gitcode.com/GitHub_Trending/um/umi

Umi 官方解决方案@umi/max内置了 Qiankun 微前端插件(实现见 qiankun 插件入口),一条配置即可开启微前端开发模式,帮助开发者在 Umi 项目中快速集成 Qiankun 微应用,构建生产可用的微前端架构。读完本文,你将掌握:父/子应用的最小化配置、三种子应用引入方式、基于useModel()的父子应用通信、生命周期钩子的完整语义,以及加载动画与错误捕获的自定义方案,并了解插件在 umi/src 与 slave 两侧的真实实现机制。

核心概念:父应用、子应用与微应用

微前端的基本模型可以这样理解:在父应用里,通过导航栏切换路由后,页面下方显示的内容来自不同的子应用。子应用支持单独打开,子应用之间也支持任意嵌套。

更直观地讲:父应用和子应用都是独立的前端项目,父应用可以在内部引入子应用,子应用也可以继续引入孙子应用,以此类推。当一个应用能够作为子应用被其它应用引入时,它就是所谓的微应用

快速开始

本教程假设你对什么是微前端、什么是 Qiankun 微应用、以及如何使用 Qiankun 微应用已有基本了解。

配置父应用

首先需要配置父应用,注册子应用的相关信息,这样父应用才能识别并在内部引入子应用。注册子应用的方式主要有两种:插件注册(构建时静态配置)与运行时注册(通过src/app.ts动态导出)。

插件注册子应用

修改父应用的 Umi 配置文件,添加如下内容:

// .umirc.ts export default { qiankun: { master: { apps: [ { name: 'app1', entry: '//localhost:7001', }, { name: 'app2', entry: '//localhost:7002', }, ], }, }, };

其中name为子应用名称,引入子应用时使用;entry为子应用运行的 HTTP 地址。master对象的完整 API 见下文 MasterOptions。

从源码看,插件对qiankun配置的 schema 校验非常宽松,qiankun.ts 中仅声明了slavemasterexternalQiankun三个字段,master的具体选项在运行时由 masterRuntimePlugin.tsx 消费。

运行时注册子应用

如果希望把子应用列表放到运行时决定,只需在配置中开启空master

// .umirc.ts export default { qiankun: { master: {}, }, };

然后在父应用的src/app.ts中导出qiankun对象:

// src/app.ts export const qiankun = { apps: [ { name: 'app1', entry: '//localhost:7001', }, { name: 'app2', entry: '//localhost:7002', }, ], };

在实现上,masterRuntimePlugin.tsx 的getMasterRuntime()会通过插件管理器应用qiankun运行时配置,拿到master(或直接是整个导出对象)后与静态的getMasterOptions()结果合并,最终写入setMasterOptions(),供<MicroApp />组件读取。

配置子应用

子应用需要导出必要的生命周期钩子,供父应用在适当时机调用。

假设你的子应用基于 Umi 开发引入了 qiankun 插件;如果不是,可以参照 Qiankun 官方入门文档自行配置(需要手动实现bootstrap/mount/unmount并挂载到window[appName])。

Utoopack 兼容性提示:如果子应用使用 utoopack 构建,且主应用使用 qiankun 2,请将主应用的 qiankun 升级至2.10.17-beta.0或更高版本。更早的版本无法在执行入口脚本时正确提供document.currentScript,会导致子应用加载失败。

修改子应用的 Umi 配置文件:

// .umirc.ts export default { qiankun: { slave: {}, }, };

仅此一行,插件就会自动为子应用创建好 Qiankun 所需的完整生命周期钩子。从 slave.ts 源码可以看到,插件实际做了大量工作:

  1. 注入生命周期:通过addEntryCode向入口注入bootstrap/mount/unmount/update四个导出(由genMountgenBootstrapgenUnmountgenUpdate生成,见 lifecycles.ts),非 Qiankun 环境下直接bootstrap().then(mount)独立运行;
  2. 设置 UMD 输出chainWebpack中将output.libraryTarget设为umdlibrary为包名api.pkg.name,确保父应用可以通过window[appName]访问到子应用导出;
  3. 默认修改 base:当 history 不是hash时,自动将子应用base设为/${pkg.name},可用shouldNotModifyDefaultBase关闭;
  4. 注入 publicPath 修正脚本window.publicPath = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__ || ...,配合默认开启的runtimePublicPath,保证子应用以任意方式部署时资源地址正确;
  5. 标记入口脚本modifyHTMLumi.js脚本标签添加entry属性(Qiankun 依赖该标记识别应用入口);utoopack 场景下还会额外注入一段生命周期代理脚本getUtoopackQiankunLifecycleProxyScript,用 Proxy 把window[appName]的读取延迟到生命周期真正注册完成,规避 utoopack 输出时序问题——这正是前文兼容性提示中版本要求的来源。

引入子应用

插件提供了三种引入子应用的方式:路由绑定<MicroApp />组件、<MicroAppWithMemoHistory />组件。

路由绑定引入子应用

手动配置.umirc.tsroutes,通过路由绑定子应用。适用场景:

  • 子应用包含完整的路由切换逻辑时;
  • 父子应用路由相互关联时。

例如想在/app1/project/app2路由分别加载app1app2

// .umirc.ts export default { routes: [ { path: '/', component: '@/layouts/index.tsx', routes: [ { path: '/app1', component: '@/layouts/app-layout.tsx', routes: [ // 配置微应用 app1 关联的路由 { // 带上 * 通配符意味着将 /app1/project 下所有子路由都关联给微应用 app1 path: '/project/*', microApp: 'app1', }, ], }, // 配置 app2 关联的路由 { path: '/app2/*', microApp: 'app2', }, ], }, ], };

配置好后,子应用的路由 base 会在运行时被设置为主应用中配置的path。例如上面 app1 关联的 path 为/app1/project,若 app1 内部有路由/user,则浏览器 URL 必须是/app1/project/user才能访问到对应页面,否则子应用匹配不到路由而渲染空白或 404。

qiankun插件扩展了 Umi 原有的路由对象,新增了microApp字段,值为注册子应用的name。切换到对应路由后,Umi 会用<MicroApp />组件渲染此子应用,并替换原来路由的component

实现上,master.ts 的modifyRoutes会把含microApp字段的路由route.file改写为一个动态import,加载模板生成的 getMicroAppRouteComponent.tsx。该组件内部用useMatch(routePath)计算pathnameBase作为子应用base(默认MicroAppRouteMode.PREPEND:路由 path 既作匹配规则又作子应用 basename,见 constants.ts),再透传给<MicroApp />

<MicroApp />组件引入子应用

通过组件直接加载(或卸载)子应用。适用场景与路由绑定相同:子应用包含完整路由逻辑、父子应用路由相互关联。

import { MicroApp } from 'umi'; export default function Page() { return <MicroApp name="app1" />; }

该方式下父子应用的路由一一对应:父应用路由为/some/page时,子应用路由同样为/some/page,切换子应用路由时父应用同步切换。如果父应用路由包含前缀,可配置base属性保证路由正确对应。例如父应用路由为/prefix/router-path/some/page时希望子应用路由为/some/page

import { MicroApp } from 'umi'; export default function Page() { return <MicroApp name="app1" base="/prefix/router-path" />; }

从 MicroApp.tsx 源码看,组件核心调用的是 Qiankun 的loadMicroApp,把container指向内部div、把settings中的base/history组装进FrameworkConfiguration;组件卸载时通过microApp._unmounting标志位与unmountMicroApp()保证 unmount 后不再触发 update。

<MicroAppWithMemoHistory />组件引入子应用

适用场景:仅使用子应用的指定路由、父子应用路由相互独立。

它是<MicroApp />的变体,需要显式提供url属性作为子应用路由;当父应用路由变化时,子应用路由不会改变

import { MicroAppWithMemoHistory } from 'umi'; export default function Page() { return <MicroAppWithMemoHistory name="app2" url="/some/page" />; }

子应用之间跳转

当子应用通过路由绑定方式引入时,在其它子应用内部可以使用<MicroAppLink />跳转到对应路由。以app1app2为例:

// 在 app1 中 import { MicroAppLink } from 'umi'; export default function Page() { return ( <> {/* 跳转链接为 /app2/home */} <MicroAppLink name="app2" to="/home"> <Button>go to app2</Button> </MicroAppLink> </> ); }

点击后父应用路由变为/app2/home,渲染app2内部路由为/home的页面。从app2跳回app1同理:

// 在 app2 中 import { MicroAppLink } from 'umi'; export default function Page() { return ( <> {/* 跳转链接为 /app1/project/home */} <MicroAppLink name="app1" to="/home"> <Button>go to app1</Button> </MicroAppLink> </> ); }

也可以从子应用跳转到父应用的指定路由:

// 在子应用中 import { MicroAppLink } from 'umi'; export default function Page() { return ( <> {/* 跳转链接为 /table */} <MicroAppLink isMaster to="/table"> <Button>go to master app</Button> </MicroAppLink> </> ); }

MicroAppLink.tsx 的实现细节:它从useModel('@@qiankunStateFromMaster')中取出__globalRoutesInfo(含microAppRoutesbasemasterHistoryType),用urlFactory按子应用 name 找到其路由 path,把path中的/*去除后作为前缀拼接到to之前生成最终 URL;browser模式下点击拦截默认行为并执行history.pushStatehash模式则生成#开头的链接由a标签默认行为完成跳转。

子应用生命周期

Qiankun 在 single-spa 的基础上实现了额外的生命钩子。按微应用生命周期顺序,完整的钩子列表为:

钩子调用时机状态变化
beforeLoad微应用开始获取前初始为NOT_LOADED
load微应用获取完成时开始获取为LOADING_SOURCE_CODE;成功变NOT_BOOTSTRAPPED,失败变LOAD_ERROR
bootstrap微应用初始化完成时开始初始化BOOTSTRAPPING;完成变NOT_MOUNTED
beforeMount每次开始挂载前-
mount每次开始挂载时变为MOUNTING
afterMount每次挂载完成时变为MOUNTED
beforeUnmount每次开始卸载前-
unmount每次开始卸载时变为UNMOUNTING
afterUnmount每次卸载完成时变为NOT_MOUNTED
unload微应用卸载完成时变为NOT_LOADED

此外还有一个特殊钩子update,仅在使用<MicroApp /><MicroAppWithMemoHistory />组件引入时生效:状态为MOUNTED的微应用手动刷新时调用;开始更新变为UPDATING,完成回到MOUNTED

手动刷新子应用的示例:

import { useRef } from 'react'; import { MicroApp } from 'umi'; export default function Page() { const microAppRef = useRef(); // 执行此方法时,更新子应用 const updateMicroApp = () => { microAppRef.current?.update(); }; return <MicroApp name="app1" ref={microAppRef} />; }

值得注意的是,除了手动update()<MicroApp />组件还会在stateForSlave或组件 props 变化时自动触发microApp.update(props)——MicroApp.tsx 用_updatingPromise链式队列保证多次 props 变更时更新按顺序串行执行,且开发环境下 200ms 内连续多次更新会打印告警提示优化重渲染。

自定义生命周期逻辑可以在父应用全局配置,也可以在子应用单独配置。

父应用配置生命周期钩子

在父应用src/app.ts导出qiankun对象进行全局配置,所有子应用都将实现这些钩子:

// src/app.ts export const qiankun = { lifeCycles: { // 所有子应用在挂载完成时,打印 props 信息 async afterMount(props) { console.log(props); }, }, };

在 MicroApp.tsx 中,全局钩子globalLifeCycles与组件 props 里的lifeCycles通过lodash/mergeWith以数组合并后传给loadMicroApp的第三个参数,即同名钩子会被依次串联执行。

子应用配置生命周期钩子

在子应用src/app.ts导出qiankun对象实现钩子。子应用运行时仅支持配置bootstrapmountunmount钩子:

// src/app.ts export const qiankun = { // 应用加载之前 async bootstrap(props) { console.log('app1 bootstrap', props); }, // 应用 render 之前触发 async mount(props) { console.log('app1 mount', props); }, // 应用卸载之后触发 async unmount(props) { console.log('app1 unmount', props); }, };

类型层面,slave.ts 生成的运行时类型声明IRuntimeConfig.qiankun为「完整SlaveOption(含enable与生命周期)」与「仅生命周期钩子」的 XOR,即qiankun: { bootstrap, mount, unmount }qiankun: { slave: { enable } }两种写法二选一。

父子应用通信

父子应用通信有两种实现方式:

  • 基于useModel()的通信——Umi推荐的方案;
  • 基于配置的通信

基于useModel()的通信

该方式基于 数据流插件,此插件已内置于@umi/max解决方案中(详见 数据流指南)。注意该通信方式要求子应用基于 Umi 开发引入了数据流插件;从 slave.ts 可以看到,若model插件未启用,生成的代码会把useModel置为null并打印警告,相关功能将不可用。

主应用透传数据

路由模式引入时,需要在父应用src/app.ts导出useQiankunStateForSlave()函数,其返回值将传递给子应用:

// src/app.ts export function useQiankunStateForSlave() { const [globalState, setGlobalState] = useState<any>({ slogan: 'Hello MicroFrontend', }); return { globalState, setGlobalState, }; }

组件模式引入时,直接将数据作为组件参数传入:

import { useState } from 'react'; import { MicroApp } from 'umi'; export default function Page() { const [globalState, setGlobalState] = useState<any>({ slogan: 'Hello MicroFrontend', }); return ( <MicroApp name="app1" globalState={globalState} setGlobalState={setGlobalState} /> ); }

实现原理(对应 master.ts 的addExtraModels逻辑):主应用侧插件发现src/app.ts导出了useQiankunStateForSlave后,会以命名空间@@qiankunStateForSlave注册一个额外 Model;<MicroApp />内部通过useModel('@@qiankunStateForSlave')读取该状态,并与配置中的props合并后传给loadMicroApp(见 MicroApp.tsx,合并顺序为propsFromConfig < stateForSlave < propsFromParams)。

子应用消费数据

子应用会自动生成一个全局 Model,命名空间为@@qiankunStateFromMaster(实现见 qiankunModel.ts,它用模块级变量缓存初始值,并在setModelState被调用时同步到 React state)。通过useModel()可在任意组件中获取并消费父应用透传的数据:

import { useModel } from 'umi'; export default function Page() { const masterProps = useModel('@@qiankunStateFromMaster'); return <div>{JSON.stringify(masterProps)}</div>; }

或者通过高阶方法connectMaster()获取数据:

import { connectMaster } from 'umi'; function MyPage(props) { return <div>{JSON.stringify(props)}</div>; } export default connectMaster(MyPage);

子应用也可以在生命周期钩子中直接使用传入的props,按需实现上文的生命周期钩子即可。

特别的,当父应用使用<MicroApp /><MicroAppWithMemoHistory />引入子应用时,会额外向子应用传递setLoading()方法,允许子应用在合适时机标记自身加载完成:

const masterProps = useModel('@@qiankunStateFromMaster'); masterProps.setLoading(false); // 或者 function MyPage(props) { props.setLoading(false); } connectMaster(MyPage);

子应用挂载完成变为MOUNTED状态时也会自动标记完成。对应地,MicroApp.tsx 中setLoading被放进loadMicroApppropsloadPromise/bootstrapPromise/mountPromise任一失败时也会执行setLoading(false)结束加载态。

基于配置的通信

在父应用注册子应用时,可以传入props属性将数据传递给子应用。例如修改父应用src/app.tsqiankun导出:

// src/app.ts export const qiankun = { apps: [ { name: 'app1', entry: '//localhost:7001', props: { accountOnClick: (event) => console.log(event), accountName: 'Alex', accountAge: 21, }, }, ], };

子应用同样在生命周期钩子中获取并使用传入的props即可。

自定义子应用

启用加载动画或错误捕获能力后,子应用的渲染结构会变为:

<div style={{ position: 'relative' }} className={wrapperClassName}> <MicroAppLoader loading={loading} /> <ErrorBoundary error={e} /> <MicroApp className={className} /> </div>

这与 MicroApp.tsx 的 JSX 完全一致:仅在microAppLoadermicroAppErrorBoundary存在时渲染外层qiankun-micro-app-wrapper容器。

子应用加载动画

启用后,子应用加载期间自动显示加载动画;子应用挂载完成变为MOUNTED时加载结束,显示子应用内容。

基于 antd 的加载动画

当使用 antd 作为组件库时,向子应用传入autoSetLoading属性即可,插件会自动调用 antd 的<Spin />组件作为加载组件(master.ts 在antd插件启用时生成 AntdLoader.tsx,否则默认 loader 只是一个打印警告的空组件)。

路由模式:

// .umirc.ts export default { routes: [ { path: '/app1', microApp: 'app1', microAppProps: { autoSetLoading: true, }, }, ], };

组件模式:

import { MicroApp } from 'umi'; export default function Page() { return <MicroApp name="app1" autoSetLoading />; }
自定义加载动画

未使用 antd 或希望覆盖默认样式时,可设置自定义loader组件。

路由模式引入的子应用只支持运行时配置:

// .app.tsx import CustomLoader from 'src/components/CustomLoader'; export const qiankun = () => ({ routes: [ { path: '/app1', microApp: 'app1', microAppProps: { loader: (loading) => <CustomLoader loading={loading} />, }, }, ], });

组件模式直接传参:

import CustomLoader from '@/components/CustomLoader'; import { MicroApp } from 'umi'; export default function Page() { return ( <MicroApp name="app1" loader={(loading) => <CustomLoader loading={loading} />} /> ); }

其中loadingboolean参数:true表示仍在加载,false表示加载结束。

若希望多个子应用统一使用同一加载动画,可在主应用配置defaultLoader(文件路径):

// .umirc.ts qiankun: { master: { defaultLoader: '@/defaultLoader', }, },

defaultLoader为文件路径,约定放在 src 目录下(参见 目录结构说明),umi 中@即代表src目录。master.ts 会断言该路径必须以@/开头,否则抛出「only support src path」错误。

// defaultLoader.tsx import { Spin } from 'antd'; export default function (loading: boolean) { return <Spin spinning={loading} />; }

注意:loader的优先级高于defaultLoader(见 MicroApp.tsx 中loader || defaultLoader || (autoSetLoading ? ...)的取值顺序)。

子应用错误捕获

启用后,子应用加载出现异常时自动显示错误信息。

基于 antd 的错误捕获组件

使用 antd 时传入autoCaptureError属性,插件会自动调用 antd 的<Result />组件(AntdErrorBoundary.tsx)作为错误捕获组件,文案语言会自动读取 umi locale 配置切换。

路由模式:

// .umirc.ts export default { routes: [ { path: '/app1', microApp: 'app1', microAppProps: { autoCaptureError: true, }, }, ], };

组件模式:

import { MicroApp } from 'umi'; export default function Page() { return <MicroApp name="app1" autoCaptureError />; }
自定义错误捕获组件

未使用 antd 或希望覆盖默认样式时,可设置自定义errorBoundary。路由模式引入的子应用只支持运行时配置:

// .app.tsx import CustomErrorBoundary from '@/components/CustomErrorBoundary'; export const qiankun = () => ({ routes: [ { path: '/app1', microApp: 'app1', microAppProps: { errorBoundary: (error) => <CustomErrorBoundary error={error} />, }, }, ], });

组件模式直接传参:

import CustomErrorBoundary from '@/components/CustomErrorBoundary'; import { MicroApp } from 'umi'; export default function Page() { return ( <MicroApp name="app1" errorBoundary={(error) => <CustomErrorBoundary error={error} />} /> ); }

其中errorError类型参数。多个子应用统一使用自定义错误组件时,可在主应用配置defaultErrorBoundary(同样是@/开头的文件路径,校验逻辑与defaultLoader相同):

// .umirc.ts qiankun: { master: { defaultErrorBoundary: '@/defaultErrorBoundary', }, },
// defaultErrorBoundary.tsx export default function (error: Error) { return <div>{error?.message}</div>; }

注意:errorBoundary的优先级高于defaultErrorBoundary。若两者都未配置且未开启autoCaptureError,MicroApp.tsx 的setComponentError会直接把异常向上抛出而非吞掉。

环境变量

如果有些配置无法显式写进.umirc.tssrc/app.ts(例如按部署环境动态注入),可以存放在环境变量文件中。父应用.env示例:

INITIAL_QIANKUN_MASTER_OPTIONS="{\"apps\":[{\"name\":\"app1\",\"entry\":\"//localhost:7001\"},{\"name\":\"app2\",\"entry\":\"//localhost:7002\"}]}"

插件内部会执行JSON.parse(process.env.INITIAL_QIANKUN_MASTER_OPTIONS),并将结果与已有配置合并。上面的环境变量等价于:

export default { qiankun: { master: { apps: [ { name: 'app1', entry: '//localhost:7001' }, { name: 'app2', entry: '//localhost:7002' }, ], // ... .umirc.ts 中其它的配置信息 }, }, };

注意:存在相同配置项时(如apps),写在.umirc.ts中的配置覆盖环境变量中的配置。这一点在 master.ts 的modifyDefaultConfig中可以直接验证:先展开JSON.parse(process.env.INITIAL_QIANKUN_MASTER_OPTIONS || '{}'),再展开config.qiankun.master,后者生效。

另外,isMasterEnable 表明:即使未配置qiankun.master,只要设置了INITIAL_QIANKUN_MASTER_OPTIONS环境变量,master 插件也会被激活。子应用同理,可编写.env

INITIAL_QIANKUN_SLAVE_OPTIONS="{\"enable\":false}"

等价于qiankun.slave.enable = false的默认配置合并(见 slave.ts 中devSourceMap: true会先作为子应用默认值,再依次与环境变量、用户配置合并)。

API 参考

MasterOptions

属性必填说明类型默认值
enable启用 Qiankun 微应用插件,设为false时不启用booleanundefined
apps微应用配置App[]undefined
routes微应用运行时的路由Route[]undefined
defaultErrorBoundary子应用默认的错误捕获组件,值为文件路径string-
defaultLoader子应用默认的加载动画,值为文件路径string-
sandbox是否开启沙箱模式boolean \| { strictStyleIsolation: boolean, experimentalStyleIsolation: boolean }true
prefetch是否启用微应用预加载boolean \| 'all' \| string[] \| (( apps: RegistrableApp[] ) => { criticalAppNames: string[]; minorAppsName: string[] })true

关于沙箱和预加载可参阅 Qiankun 官方 API 文档。从源码看,prefetch的实际行为在 masterRuntimePlugin.tsx 与 MicroApp.tsx 中:'all'时对所有未配置base的应用执行prefetchAppsstring[]时只预取名单内应用;true时则延迟到第一个微应用mountPromise完成后,预取其它未挂载应用且受prefetchThreshold(默认 5)阈值限制,避免无脑全量预取。

SlaveOptions

属性必填说明类型默认值
enable启用 Qiankun 微应用插件,设为false时不启用booleanundefined

源码中还存在若干未列入文档的实用选项,例如 slave.ts 使用的shouldNotModifyDefaultBase(阻止自动设置base = /${pkg.name})、shouldNotModifyRuntimePublicPath(不注入 publicPath 脚本)、shouldNotAddLibraryChunkName(生产环境默认true,本地配合 MFSU 时可改库名规则)、masterEntry(本地开发时把请求代理到主应用地址,见addMiddlewares中的 proxy 实现)等,可按需查阅源码。

App

属性必填说明类型默认值
name微应用的名称string-
entry微应用的 HTML 地址string{ script: string[], styles: [] }
credentials拉取微应用时同时拉取 Cookiesbooleanfalse
props父应用传递给微应用的数据,详见父子应用通信object{}

credentials: true的实现在 masterRuntimePlugin.tsx:插件会包装window.fetch,当请求 URL 命中开启了credentials的应用 entry 时,自动附加mode: 'cors'credentials: 'include'

Route

属性必填说明类型默认值
path路由 PATHstring-
microApp关联的微应用名称string-
microAppProps微应用的配置MicroAppProps{}

MicroAppProps

属性必填说明类型默认值
autoSetLoading自动设置微应用的加载状态booleanfalse
loader自定义的微应用加载状态组件(loading) => React.ReactNodeundefined
autoCaptureError自动设置微应用的错误捕获booleanfalse
errorBoundary自定义的微应用错误捕获组件(error: any) => React.ReactNodeundefined
className微应用的样式类stringundefined
wrapperClassName包裹微应用加载组件、错误捕获组件和微应用的样式类,仅在启用加载组件或错误捕获组件时有效stringundefined

补充说明:MicroApp.tsx 的Props类型还接受basehistory'hash' | 'browser' | 'memory'或对应 history 对象)、settings(Qiankun 的FrameworkConfiguration)、onHistoryInit等属性,组件内其余透传属性(...propsFromParams)都会进入传给子应用的 props。

FAQ:生命周期钩子已执行,但页面没有渲染

如果页面没有报错,且查看 DOM 发现子应用根节点已经存在、只是内容为空,基本可以确定是当前 URL 没有匹配到子应用的任何路由导致的。

比如主应用中配置了:

{ path: '/app1', microApp: 'app1', }

子应用的路由配置是:

{ path: '/user', component: './User', }

那么必须通过/app1/user路径才能正常访问到子应用的 user 页面。这正是「子应用路由 base 在运行时被设置为主应用配置的path」这一机制的直接结果(参见前文 getMicroAppRouteComponent.tsx 中prefixbase的拼接逻辑)。排查此类问题时,先确认浏览器 URL 是否等于「主应用路由 path + 子应用内部路由」,再检查子应用自身的base配置是否与主应用传入的一致。

【免费下载链接】umiA framework in react community ✨项目地址: https://gitcode.com/GitHub_Trending/um/umi

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询