import { noop } from 'lodash'; import { mountRootParcel, registerApplication, start as startSingleSpa } from 'single-spa'; import { FrameworkConfiguration, FrameworkLifeCycles, LoadableApp, MicroApp, RegistrableApp } from './interfaces'; import { loadApp } from './loader'; import { doPrefetchStrategy } from './prefetch'; import { Deferred, toArray } from './utils'; let microApps: RegistrableApp[] = []; // eslint-disable-next-line import/no-mutable-exports export let frameworkConfiguration: FrameworkConfiguration = {}; const frameworkStartedDefer = new Deferred(); export function registerMicroApps( apps: Array>, lifeCycles?: FrameworkLifeCycles, ) { // Each app only needs to be registered once const unregisteredApps = apps.filter(app => !microApps.some(registeredApp => registeredApp.name === app.name)); microApps = [...microApps, ...unregisteredApps]; unregisteredApps.forEach(app => { const { name, activeRule, loader = noop, props, ...appConfig } = app; registerApplication({ name, app: async () => { loader(true); 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, }); }); } export function loadMicroApp( app: LoadableApp, configuration?: FrameworkConfiguration, lifeCycles?: FrameworkLifeCycles, ): MicroApp { const { props } = app; return mountRootParcel(() => loadApp(app, configuration ?? frameworkConfiguration, lifeCycles), { domElement: document.createElement('div'), ...props, }); } export function start(opts: FrameworkConfiguration = {}) { frameworkConfiguration = { prefetch: true, singular: true, sandbox: true, ...opts }; const { prefetch, sandbox, singular, urlRerouteOnly, ...importEntryOpts } = frameworkConfiguration; if (prefetch) { doPrefetchStrategy(microApps, prefetch, importEntryOpts); } if (sandbox) { if (!window.Proxy) { console.warn('[qiankun] Miss window.Proxy, proxySandbox will degenerate into snapshotSandbox'); // 快照沙箱不支持非 singular 模式 if (!singular) { console.error('[qiankun] singular is forced to be true when sandbox enable but proxySandbox unavailable'); frameworkConfiguration.singular = true; } } } startSingleSpa({ urlRerouteOnly }); frameworkStartedDefer.resolve(); }