当前文档对应 qiankun 3.0(RC),安装请使用 npm i qiankun@rc;2.x 文档见 v2 站点。
Skip to content

loadMicroApp ​

loadMicroApp 是 qiankun 推荐的微应用加载 API。它将微应用挂载到指定的 DOM 元素,并返回管理该实例的句柄。页面区域、标签页、弹窗,以及由主应用状态控制的微应用,均可采用这一方式。

仅当应用必须根据 URL 自动激活时,才需要使用 registerMicroApps 和 start。

React <MicroApp> 和 Vue <MicroApp> 组件均基于该函数实现。

函数签名 ​

ts
function loadMicroApp<T extends ObjectType>(
  app: LoadableApp<T>,
  configuration?: AppConfiguration,
  lifeCycles?: LifeCycles<T>,
): MicroApp;

loadMicroApp 返回一个 MicroApp 句柄,其底层类型为 single-spa Parcel。该句柄可用于查询状态和卸载应用。函数不会等待加载和挂载完成;如需确定各阶段的完成时机,应等待句柄中对应的 Promise。

参数 ​

app: LoadableApp<T> ​

用于描述待加载的微应用及其挂载位置。

字段类型必填说明
namestring是微应用名称。多个实例可以复用名称;只有并发挂载的实例需要使用不同容器。
entrystring是微应用 HTML 入口的 URL。仅支持字符串;v3 不再支持 2.x 的对象形式({ scripts, styles })。
containerHTMLElement是用于渲染微应用的 DOM 元素。必须传入实际元素,不能使用 CSS 选择器字符串。
propsT否传递给 mount、unmount 和可选 update 的业务数据,不传入 bootstrap。
ts
type ObjectType = Record<string, unknown>;

type LoadableApp<T extends ObjectType> = {
  name: string;
  entry: string;
  container: HTMLElement;
  props?: T;
};

container 必须是元素

在 qiankun v3 中,container 的类型为 HTMLElement,不再接受 string | HTMLElement。调用前应通过 document.getElementById(...) 或框架提供的 ref 获取实际元素。传入选择器字符串会导致类型错误,运行时也无法正常挂载。

configuration?: AppConfiguration ​

单个应用的运行时配置。所有配置项均为可选,默认值由 qiankun 内部处理。

选项类型默认值说明
sandboxboolean | SandboxConfigurationtrue启用基于 Proxy 隔离膜的 JavaScript 隔离和原生 ESM 支持。仅当旧应用必须在真实全局对象中运行时,才应设为 false;传入对象则在保持隔离的同时配置沙箱。
fetchtypeof window.fetchwindow.fetch用于请求入口,以及由加载器处理的脚本、模块和样式的自定义 fetch。
streamTransformer() => TransformStream<string, string>—用于自定义 HTML 流式处理过程的可选转换流。
nodeTransformerNodeTransformer内部默认值在 <script>、<link> 和 <style> 节点进入真实 DOM 前进行转换。仅高级扩展场景需要覆盖。
ts
type AppConfiguration = Partial<Pick<LoaderOpts, 'fetch' | 'streamTransformer' | 'nodeTransformer'>> & {
  sandbox?: boolean | SandboxConfiguration;
};

sandbox 是隔离能力的统一入口。它的对象形式承载 styleIsolation、globals、incubatorContext、plugins 以及 Compartment 模块钩子:

ts
loadMicroApp(app, {
  sandbox: {
    styleIsolation: true,
    globals: { TENANT_ID: 'acme' },
  },
});

完整的配置参考见 AppConfiguration。

lifeCycles?: LifeCycles<T> ​

可选的生命周期钩子,在该应用加载、挂载和卸载的相应阶段触发。每个钩子可以是单个函数或函数数组,签名均为 (app, global),其中 global 表示经过沙箱隔离的 window 视图。

ts
type LifeCycleFn<T extends ObjectType> = (app: LoadableApp<T>, global: WindowProxy) => Promise<void>;

type LifeCycles<T extends ObjectType> = {
  beforeLoad?: LifeCycleFn<T> | Array<LifeCycleFn<T>>;
  beforeMount?: LifeCycleFn<T> | Array<LifeCycleFn<T>>;
  afterMount?: LifeCycleFn<T> | Array<LifeCycleFn<T>>;
  beforeUnmount?: LifeCycleFn<T> | Array<LifeCycleFn<T>>;
  afterUnmount?: LifeCycleFn<T> | Array<LifeCycleFn<T>>;
};

细节见生命周期钩子。

返回值 ​

loadMicroApp 返回兼容 single-spa Parcel 接口的 MicroApp 句柄:

ts
type MicroApp = Parcel;

type Parcel = {
  mount(): Promise<null>;
  unmount(): Promise<null>;
  update?(customProps: object): Promise<any>;
  getStatus():
    | 'NOT_LOADED'
    | 'LOADING_SOURCE_CODE'
    | 'NOT_BOOTSTRAPPED'
    | 'BOOTSTRAPPING'
    | 'NOT_MOUNTED'
    | 'MOUNTING'
    | 'MOUNTED'
    | 'UPDATING'
    | 'UNMOUNTING'
    | 'UNLOADING'
    | 'SKIP_BECAUSE_BROKEN'
    | 'LOAD_ERROR';
  loadPromise: Promise<null>;
  bootstrapPromise: Promise<null>;
  mountPromise: Promise<null>;
  unmountPromise: Promise<null>;
};
成员说明
mount()挂载该 Parcel。loadMicroApp 会在加载时自动挂载,因此通常无需直接调用。
unmount()卸载应用、停用沙箱,并清理可追踪的副作用和容器 DOM。不再使用应用时必须调用。
update?(props)仅当微应用导出 update 生命周期时存在,用于向运行中的应用传递新的 props。
getStatus()返回当前生命周期状态,取值范围为上述联合类型。
loadPromise表示源码加载阶段完成的 Promise。
bootstrapPromise表示 bootstrap 阶段完成的 Promise。
mountPromise表示挂载阶段完成的 Promise。可等待该 Promise,以确认应用已完成渲染。
unmountPromise表示卸载阶段完成的 Promise。

句柄上的四个 Promise 保持 single-spa Parcel 的单次语义,分别对应首次加载、首次 bootstrap、首次挂载和首次卸载,不会在重新挂载时替换。后续调用 mount()、unmount() 时,应等待方法返回的 Promise;已完成的 mountPromise、unmountPromise 不能用于等待后续轮次。

处理 Promise 拒绝

加载或挂载失败时,这些 Promise 会被拒绝。应通过 .catch 或 try...catch 处理错误,避免产生未处理的 Promise 拒绝。

行为 ​

  • 调用后立即开始加载和挂载。 无需预先调用 start();如需等待应用完成渲染,应等待 mountPromise。
  • 一个容器在同一时刻只承载一个应用。 如果连续向同一容器加载应用,后一个实例会等待前一个实例卸载。
  • 同名应用优先复用已有实例。 以相同的 name 和 entry 再次调用时,qiankun 优先复用空闲实例,不再执行入口和 bootstrap。没有空闲实例时,也可以等待满足复用条件的卸载中实例;没有可复用实例时则重新加载。同一 name 应始终指向同一个应用,每次挂载所需的状态应在 mount() 中初始化。
  • 空闲实例有数量和时间限制。 同一 name 和 entry 最多保留 2 份空闲实例,全局最多保留 8 份;超限时淘汰最久未使用的空闲实例,连续空闲 5 分钟后也会回收。正在加载、挂载、排队或卸载的实例不参与淘汰。回收不清空独立的资源请求缓存。
  • 回收后旧句柄仍可重新挂载。 unmount() 后可以再次调用原句柄的 mount();命中缓存时复用沙箱,缓存已回收且没有其他可复用实例时,重新加载并执行入口、bootstrap 和 mount。不应依赖模块顶层代码在每次挂载时必定执行或必定不执行。
  • 调用方负责卸载。 不再展示应用时应调用 unmount(),以便 qiankun 清空容器并释放能够追踪的资源和副作用。

多实例、复用和重新挂载的完整建议见运行多个微应用实例。

示例 ​

以下示例先获取 container 元素并挂载应用,在不再需要该应用时将其卸载。

ts
import { loadMicroApp } from 'qiankun';

const container = document.getElementById('micro-app-slot');
if (!container) throw new Error('container not found');

const microApp = loadMicroApp(
  {
    name: 'app1',
    entry: 'http://localhost:7101',
    container,
    props: { userId: 42 },
  },
  { sandbox: true },
);

// 等待应用完成挂载
await microApp.mountPromise;
console.log(microApp.getStatus()); // 'MOUNTED'

// 不再需要时卸载应用
await microApp.unmount();

如果旧应用无法在隔离环境中运行,可以关闭沙箱:

ts
const microApp = loadMicroApp({ name: 'legacy-app', entry: 'http://localhost:7200', container }, { sandbox: false });

React 和 Vue 组件

如果主应用使用 React 或 Vue,也可以使用对应的 <MicroApp> 组件管理容器引用、props 更新和实例卸载。组件内部采用与 loadMicroApp 相同的实例模型。

相关内容 ​

基于 MIT 协议发布