ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

qiankun 微前端运行时:使用 loadMicroApp 管理单个微应用实例的完整指南

qiankun 微前端运行时:使用 loadMicroApp 管理单个微应用实例的完整指南 qiankun 微前端运行时使用 loadMicroApp 管理单个微应用实例的完整指南【免费下载链接】qiankun Blazing fast, simple and complete solution for micro frontends.项目地址: https://gitcode.com/gh_mirrors/qi/qiankun在 qiankun当前仓库 v3中loadMicroApp是官方推荐的按需加载 API主应用把一个独立开发、独立发布的微应用挂载到页面中指定的HTMITELEMENT区域并拿到一个可查询状态、可更新、可卸载的实例句柄。本文将围绕 qiankun 首页文档的核心主题结合仓库源码与示例完整讲解loadMicroApp的参数、返回值、实例管理方式、底层原理以及与基于路由的registerMicroApps/start方案的选型边界帮助你准确地在页面区域、弹窗、标签页等场景中编排微应用实例。快速开始安装与第一个微应用实例qiankun v3 目前发布在 npm 的rc标签上安装时必须显式指定rc否则latest标签指向的仍是 2.xnpm install qiankunrc::: tip 版本说明 qiankun 3.0 仍处于 RC 阶段。它保留了 HTML 入口和生命周期模型同时重写了运行时并新增原生 ESM 支持详见 what-is-qiankun。从 2.x 升级时需注意默认值和类型的变化见 migrate-from-2x。 :::安装完成后只要拿到容器元素即可加载微应用。注意保存loadMicroApp返回的实例句柄后续查询状态、卸载实例都要靠它import { loadMicroApp } from qiankun; const container document.getElementById(micro-app-slot); if (!container) throw new Error(micro-app-slot not found); const microApp loadMicroApp({ name: orders, entry: //localhost:7101, container, }); await microApp.mountPromise; // 页面区域销毁前卸载微应用 await microApp.unmount();这就是首页文档给出的最简闭环创建容器 → 加载微应用 → 等待挂载 → 不再需要时卸载。微应用只需导出bootstrap、mount和unmountqiankun 会把它加载进指定的HTMLElement并调用相应的生命周期函数。完整的可运行脚手架见 快速上手。仓库中的示例应用两个主应用加载同一组微应用分别为 React 与 Vue 技术栈位于 examples/main 与 examples/vue-host可直接作为参考。函数签名与参数详解loadMicroApp的完整签名定义在 packages/qiankun/src/apis/loadMicroApp.tsfunction loadMicroAppT extends ObjectType( app: LoadableAppT, configuration?: AppConfiguration, lifeCycles?: LifeCyclesT, ): MicroApp;对应的类型定义见 packages/qiankun/src/types.ts 与 packages/qiankun/src/types.ts。app: LoadableAppT——描述微应用及其挂载位置字段类型必填说明namestring是微应用名称。多个实例可以复用名称只有并发挂载的实例需要使用不同容器。entrystring是微应用 HTML 入口的 URL。v3 仅支持字符串形式2.x 的{ scripts, styles }对象形式不再支持。containerHTMLElement是用于渲染微应用的 DOM 元素。必须传入实际元素不能使用 CSS 选择器字符串。propsT否传递给微应用生命周期函数的数据例如用户 ID、租户标识等。::: warningcontainer必须是元素 在 qiankun v3 中container的类型为HTMLElement不再接受string | HTMLElement。调用前应通过document.getElementById(...)或框架提供的 ref 获取实际元素。传入选择器字符串会导致类型错误运行时也无法正常挂载。 :::entry对应的服务器必须返回允许主应用访问的 CORS 响应头因为 qiankun 需要跨源获取入口 HTML 及其资源。configuration?: AppConfiguration——单实例运行时配置所有配置项均为可选默认值由 qiankun 内部处理类型定义见 types.ts选项类型默认值说明sandboxboolean \| SandboxConfigurationtrue启用基于 Proxy 隔离膜的 JavaScript 隔离和原生 ESM 支持。仅当旧应用必须在真实全局对象中运行时才设为false传入对象则在保持隔离的同时配置沙箱。fetchtypeof window.fetchwindow.fetch用于请求入口以及由加载器处理的脚本、模块和样式的自定义 fetch。streamTransformer() TransformStreamstring, string—用于自定义 HTML 流式处理过程的可选转换流。nodeTransformerNodeTransformer内部默认值在script、link和style节点进入真实 DOM 前进行转换仅高级扩展场景需要覆盖。sandbox是隔离能力的统一入口其对象形式可承载styleIsolation、globals、incubatorContext、plugins以及 Compartment 模块钩子loadMicroApp(app, { sandbox: { styleIsolation: true, // 启用 CSS scope 样式隔离 globals: { TENANT_ID: acme }, }, });完整的配置参考见 AppConfiguration。lifeCycles?: LifeCyclesT——实例级生命周期钩子可选的生命周期钩子在该应用加载、挂载和卸载的相应阶段触发。每个钩子可以是单个函数或函数数组签名均为(app, global) Promisevoid其中global表示经过沙箱隔离的window视图Proxy 隔离膜而不是真实的windowtype LifeCycleFnT extends ObjectType (app: LoadableAppT, global: WindowProxy) Promisevoid; type LifeCyclesT extends ObjectType { beforeLoad?: LifeCycleFnT | ArrayLifeCycleFnT; beforeMount?: LifeCycleFnT | ArrayLifeCycleFnT; afterMount?: LifeCycleFnT | ArrayLifeCycleFnT; beforeUnmount?: LifeCycleFnT | ArrayLifeCycleFnT; afterUnmount?: LifeCycleFnT | ArrayLifeCycleFnT; };这些钩子与微应用自身导出的bootstrap/mount/unmount不同它们运行在主应用侧用于在微应用生命周期前后执行框架级逻辑例如展示加载动画、埋点上报等。细节见 生命周期钩子。返回值MicroApp 实例句柄loadMicroApp返回MicroApp其底层类型是 single-spa 的 Parcel类型别名见 types.ts。函数本身不会等待加载和挂载完成如需确定各阶段的完成时机应等待句柄中对应的 Promise成员说明mount()挂载该 Parcel。loadMicroApp会在加载时自动挂载因此通常无需直接调用。unmount()卸载应用、停用沙箱并清理可追踪的副作用和容器 DOM。不再使用应用时必须调用。update?(props)仅当微应用导出update生命周期时存在用于向运行中的应用传递新的 props。getStatus()返回当前生命周期状态取值范围包括NOT_LOADED、LOADING_SOURCE_CODE、BOOTSTRAPPING、NOT_MOUNTED、MOUNTING、MOUNTED、UPDATING、UNMOUNTING、UNLOADING、SKIP_BECAUSE_BROKEN、LOAD_ERROR。loadPromise表示源码加载阶段完成的 Promise。bootstrapPromise表示 bootstrap 阶段完成的 Promise。mountPromise表示挂载阶段完成的 Promise。可等待该 Promise以确认应用已完成渲染。unmountPromise表示卸载阶段完成的 Promise。::: warning 处理 Promise 拒绝 加载或挂载失败时这些 Promise 会被拒绝。应通过.catch或try...catch处理错误避免产生未处理的 Promise 拒绝。详细的错误处理策略见 error-handling。 :::一个带 props 传递与错误处理的完整示例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();如果旧应用无法在隔离环境中运行可以关闭沙箱const microApp loadMicroApp( { name: legacy-app, entry: http://localhost:7200, container }, { sandbox: false }, );微应用的接入契约被加载的微应用仍是标准的独立前端应用Vite、Webpack 均可只需满足两个接入要求入口模块导出bootstrap、mount和unmount三个生命周期函数——mount在主应用提供的容器内渲染unmount销毁框架根节点。使用构建插件配置 HTML 入口与开发服务器例如qiankunjs/bundler-plugin见 bundler-plugin。生命周期函数的查找顺序在 loadApp.ts 的getLifecyclesFromExports中实现优先读取入口执行结果ESM 应用读取模块导出Classic 应用读取入口脚本的导出值其次尝试export default { bootstrap, mount, unmount }形式最后才回退到window[appName]全局变量。正常解析流程不要求name与packageName或 Webpack 的output.library.name相同。微应用在直接访问自身端口时走独立运行分支自行渲染因此可以独立开发、独立发布再由主应用在运行时组合。这正对应首页文档所述的核心价值每个微应用可独立选择技术栈、管理代码仓库并安排发布主应用只在运行时把它们组合到页面上。源码视角loadMicroApp 实例管理的底层原理理解了用法后深入 packages/qiankun/src/apis/loadMicroApp.ts 可以看清几个关键实现事实以「name 容器 XPath」作为实例缓存键。在 L19-L23函数开头就会计算容器的 XPath 并保持稳定避免运行时 DOM 结构变化导致计算不一致。appConfigPromiseGetterMap以${name}-${xpath}为键缓存加载结果若同一名称的微应用挂载到之前渲染过的 DOM其生命周期不会重复加载和求值见 L67-L93。同一容器上的实例串行卸载。当多个微应用挂载到同一容器时新实例的mount会被包装先等待同一容器上前置实例全部完成卸载再继续见 L32-L46避免并发操作导致的 DOM 竞争。loadMicroApp内部会自动调用start()。在 L95-L101如果运行时尚未启动函数会主动调用 single-spa 的start以确保主应用pushState/replaceState时能正确派发popstate事件。因此按需加载场景无需显式调用start()。卸载后自动清理引用。实例挂载后会被登记进containerMicroAppsMapunmountPromise完成后从登记表中移除并将内部引用置空见 L109-L124让长生命周期的 remount 闭包可以被 GC 回收。底层的挂载/卸载链。在 loadApp.ts 中parcelConfig的mount链依次执行loader 指示true→ 容器占用container gate→ 首次或重挂载时重建容器 DOM →mountSandbox→beforeMount钩子 → 微应用mount→afterMount钩子 → loader 指示falseunmount链则执行beforeUnmount→ 微应用unmount→ 停用沙箱 →afterUnmount→ 清空容器。每条链都被失败回退包装挂载失败时也会释放容器占用避免后续实例被永久阻塞见 L271-L290。这些实现共同保证了首页文档强调的实例管理行为调用后立即开始加载和挂载无需预先调用start()一个容器在同一时刻只承载一个应用相同名称和容器可能复用已加载内容因此不应依赖模块顶层代码在重新挂载时再次执行每次挂载所需的状态应在mount()中初始化调用方负责卸载不再展示应用时应调用unmount()。多实例、复用和重新挂载的完整建议见 运行多个微应用实例。与路由驱动方案 registerMicroApps 的选型首页文档明确指出如果微应用的激活状态完全取决于当前 URL可使用基于路由的registerMicroApps和startAPI 见 register-micro-apps 与 start。两种方案的对比如下维度loadMicroAppregisterMicroAppsstart触发方式业务代码按需调用URL 匹配activeRule自动激活适用场景页面区域、弹窗、标签页、组件嵌入、由主应用状态控制挂载状态完全由 URL 决定是否调用start()内部自动调用必须显式调用实例管理手动持有句柄、手动卸载qiankun/single-spa 自动挂载与卸载名称去重复用名称不同容器可并发按name去重重名注册被忽略路由驱动的典型接入方式完整示例见 e2e/fixtures/main/src/register.tsimport { registerMicroApps, start } from qiankun; registerMicroApps([ { name: react, entry: //localhost:7100, container, activeRule: /react, loader: (loading) onLoading(react, loading), configuration: { sandbox: { styleIsolation: true } }, }, ]); start();需要注意 v3 的变更start()不再接收 2.x 的全局框架选项prefetch、sandbox、singular、getPublicPath、getTemplate等均已移除这些配置现在必须在每个应用的configuration中按应用设置。样式隔离改为布尔配置sandbox.styleIsolation底层基于 CSSscope实现。另外 v3 不再提供initGlobalState/onGlobalStateChange/setGlobalState应用间共享状态时应通过props传递自定义方法或状态容器见 communicate-between-apps。实战在 React 主应用中管理实例生命周期结合 快速上手 中的模式在 React 中通过useRef持有容器、useEffect管理加载与清理import { loadMicroApp } from qiankun; import { useEffect, useRef } from react; export default function App() { const containerRef useRefHTMLDivElement(null); useEffect(() { const container containerRef.current; if (!container) return; const microApp loadMicroApp({ name: sub-app, entry: //localhost:7101, container, }); return () { void microApp.unmount().catch((error: unknown) { console.error(sub-app 卸载失败, error); }); }; }, []); return div ref{containerRef} /; }要点useEffect的清理函数不能返回 Promise因此这里只是发起卸载并捕获可能的失败如果主应用的清理流程支持异步等待则应在移除容器前等待unmount()完成。仓库中的真实示例examples/main/src/App.tsx 配合 examples/main/src/apps.ts 与 examples/main/src/components/Stage.tsx展示了基于路由选择微应用、再由组件挂载/卸载实例的完整形态。如果主应用使用 React 或 Vue也可以直接使用对应的MicroApp组件react、vue由组件内部管理容器引用、props 更新和实例卸载——组件底层采用与loadMicroApp相同的实例模型。小结loadMicroApp是 qiankun 推荐的微应用加载 API它把「加载 HTML 入口 → 初始化沙箱 → 执行生命周期 → 挂载到指定容器」封装成一个可编程控制的实例并返回一个句柄供你查询状态、更新 props 和卸载实例。页面区域、标签页、弹窗以及由主应用状态控制的微应用均可采用这一方式仅当应用必须根据 URL 自动激活时才需要切换到registerMicroAppsstart的路由驱动方案。想要进一步深入可以继续阅读仓库中的相关文档完整的 loadMicroApp API 参考、AppConfiguration 配置、生命周期与 props以及 运行多个微应用实例 的实践建议。【免费下载链接】qiankun Blazing fast, simple and complete solution for micro frontends.项目地址: https://gitcode.com/gh_mirrors/qi/qiankun创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表