qiankun源码分析-1.注册子应用

注册子应用

注册子应用,通过registerMicroApps方法,参数为MicroApp[]和LifeCycles,MicroApp为子应用的配置项,包含name、entry、container、activeRule、props等属性。

js 复制代码
registerMicroApps(
  [
    {
      name: 'react16',
      entry: '//localhost:7100',
      container: '#subapp-viewport',
      loader,
      activeRule: '/react16',
    },
    {
      name: 'vue',
      entry: '//localhost:7101',
      container: '#subapp-viewport',
      loader,
      activeRule: '/vue',
    },
  ],
  {
    beforeLoad: [
      (app) => {
        console.log('[LifeCycle] before load %c%s', 'color: green;', app.name);
      },
    ],
    beforeMount: [
      (app) => {
        console.log('[LifeCycle] before mount %c%s', 'color: green;', app.name);
      },
    ],
    afterUnmount: [
      (app) => {
        console.log('[LifeCycle] after unmount %c%s', 'color: green;', app.name);
      },
    ],
  },
);

第一个参是是我们的子应用数组,第二个参数是生命周期钩子函数,我们可以利用这些钩子在子应用挂载的不同的阶段插入一些事情,源码如下:

js 复制代码
export function registerMicroApps<T extends ObjectType>(
  apps: Array<RegistrableApp<T>>,
  lifeCycles?: FrameworkLifeCycles<T>,
) {
  // Each app only needs to be registered once
  // 过滤出未注册的app
  const unregisteredApps = apps.filter((app) => !microApps.some((registeredApp) => registeredApp.name === app.name));

  // 未注册的app合并到microApps
  microApps = [...microApps, ...unregisteredApps];

  // 遍历未注册的app,注册到single-spa
  unregisteredApps.forEach((app) => {
    const { name, activeRule, loader = noop, props, ...appConfig } = app;

   // 调用single-spa的registerApplication方法注册子应用
    registerApplication({
      name,
      app: async () => {
        await frameworkStartedDefer.promise;

        const { mount, ...otherMicroAppConfigs } = (
          await loadApp({ name, props, ...appConfig }, frameworkConfiguration, lifeCycles)
        )();

        return {
          mount: [async () => loader(true), ...toArray(mount), async () => loader(false)],
          ...otherMicroAppConfigs,
        };
      },
      activeWhen: activeRule,
      customProps: props,
    });
  });
}

总结下:

registerMicroApps的主要目的就是注册子q应用,最终调用single-spas的registerApplication方法注册子应用,single-spa的registerApplication我们在之前的文章中有介绍到,其目的是注册子应用,并且给子应用添加默认的 初始状态,然后调用reroute函数,继而会调用loadsApp去加载所有待加载的应用,其实此时是不会加载任何app的,因为我们的路由还没有匹配到任何子应用,所以也就不会调用loadApp去加载子应用,当路由匹配到子应用时,single-spa会调用loadApp去加载子应用,那么这个阶段的流程调用图如下:

下一节我们分析第二阶段:初始化全局数据

相关推荐
颜酱3 小时前
图结构完全解析:从基础概念到遍历实现
javascript·后端·算法
失忆爆表症4 小时前
05_UI 组件库集成指南:Shadcn/ui + Tailwind CSS v4
前端·css·ui
小迷糊的学习记录4 小时前
Vuex 与 pinia
前端·javascript·vue.js
发现一只大呆瓜4 小时前
前端性能优化:图片懒加载的三种手写方案
前端·javascript·面试
不爱吃糖的程序媛4 小时前
Flutter 与 OpenHarmony 通信:Flutter Channel 使用指南
前端·javascript·flutter
利刃大大4 小时前
【Vue】Element-Plus快速入门 && Form && Card && Table && Tree && Dialog && Menu
前端·javascript·vue.js·element-plus
NEXT065 小时前
AI 应用工程化实战:使用 LangChain.js 编排 DeepSeek 复杂工作流
前端·javascript·langchain
念风零壹5 小时前
AI 时代的前端技术:从系统编程到 JavaScript/TypeScript
前端·ai
光影少年5 小时前
react的hooks防抖和节流是怎样做的
前端·javascript·react.js
小毛驴8505 小时前
Vue 路由示例
前端·javascript·vue.js