Skip to content

Commit

Permalink
feat: pass container with parameters rather than getter function
Browse files Browse the repository at this point in the history
  • Loading branch information
kuitos committed Nov 23, 2023
1 parent feb544f commit e5bc69e
Show file tree
Hide file tree
Showing 8 changed files with 23 additions and 36 deletions.
2 changes: 1 addition & 1 deletion packages/qiankun/src/apis/loadMicroApp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ export function loadMicroApp<T extends ObjectType>(
const parcelConfigObjectGetterPromise = loadApp(app, userConfiguration, lifeCycles);

if (containerXPath) {
const appContainerXPathKey = `${name}-${containerXPath}`;
const appContainerXPathKey = getContainerXPathKey(containerXPath);
appConfigPromiseGetterMap.set(appContainerXPathKey, parcelConfigObjectGetterPromise);
}

Expand Down
4 changes: 2 additions & 2 deletions packages/qiankun/src/apis/registerMicroApps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { toArray } from '../utils';

export let started = false;

let microApps: Array<RegistrableApp<Record<string, unknown>>> = [];
export const microApps: Array<RegistrableApp<Record<string, unknown>>> = [];
const frameworkConfiguration: AppConfiguration = {};

const frameworkStartedDefer = new Deferred<void>();
Expand All @@ -17,7 +17,7 @@ export function registerMicroApps<T extends ObjectType>(apps: Array<RegistrableA
// Each app only needs to be registered once
const unregisteredApps = apps.filter((app) => !microApps.some((registeredApp) => registeredApp.name === app.name));

microApps = [...microApps, ...unregisteredApps];
microApps.push(...unregisteredApps);

unregisteredApps.forEach((app) => {
const { name, activeRule, loader = noop, props, entry, container } = app;
Expand Down
20 changes: 11 additions & 9 deletions packages/qiankun/src/core/loadApp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export default async function loadApp<T extends ObjectType>(
): Promise<ParcelConfigObjectGetter> {
const { name: appName, entry, container } = app;
const defaultNodeTransformer: AppConfiguration['nodeTransformer'] = (node, opts) => {
const moduleResolver = (url: string) => defaultModuleResolver(url, sandboxMicroAppContainer, document.head);
const moduleResolver = (url: string) => defaultModuleResolver(url, microAppDOMContainer, document.head);
return transpileAssets(node, entry, { ...opts, moduleResolver });
};
const {
Expand All @@ -49,15 +49,15 @@ export default async function loadApp<T extends ObjectType>(
}

let global = globalContext;
let mountSandbox = () => Promise.resolve();
let mountSandbox: (container: HTMLElement) => Promise<void> = () => Promise.resolve();
let unmountSandbox = () => Promise.resolve();
let sandboxInstance: Sandbox | undefined;

let sandboxMicroAppContainer: HTMLElement = container;
initContainer(sandboxMicroAppContainer, appName, sandbox);
let microAppDOMContainer: HTMLElement = container;
initContainer(microAppDOMContainer, appName, sandbox);

if (sandbox) {
const sandboxContainer = createSandboxContainer(appName, () => sandboxMicroAppContainer, {
const sandboxContainer = createSandboxContainer(appName, () => microAppDOMContainer, {
globalContext,
extraGlobals: {},
fetch: fetchWithLruCache,
Expand All @@ -67,7 +67,7 @@ export default async function loadApp<T extends ObjectType>(
sandboxInstance = sandboxContainer.instance;
global = sandboxInstance.globalThis;

mountSandbox = () => sandboxContainer.mount();
mountSandbox = (domContainer) => sandboxContainer.mount(domContainer);
unmountSandbox = () => sandboxContainer.unmount();
}

Expand All @@ -78,7 +78,7 @@ export default async function loadApp<T extends ObjectType>(
...restConfiguration,
};

const lifecyclesPromise = loadEntry<MicroAppLifeCycles>(entry, sandboxMicroAppContainer, containerOpts);
const lifecyclesPromise = loadEntry<MicroAppLifeCycles>(entry, microAppDOMContainer, containerOpts);

const assetPublicPath = calcPublicPath(entry);
const {
Expand Down Expand Up @@ -123,7 +123,7 @@ export default async function loadApp<T extends ObjectType>(
}
},
async () => {
sandboxMicroAppContainer = mountContainer;
microAppDOMContainer = mountContainer;

// while the micro app is remounting, we need to load the entry manually
if (mountTimes > 1) {
Expand All @@ -133,7 +133,9 @@ export default async function loadApp<T extends ObjectType>(
await loadEntry(htmlString, mountContainer, containerOpts);
}
},
mountSandbox,
async () => {
await mountSandbox(mountContainer);
},
// exec the chain after rendering to keep the behavior with beforeLoad
async () => execHooksChain(toArray(beforeMount), app, global),
async (props) => mount({ ...props, container: mountContainer }),
Expand Down
2 changes: 0 additions & 2 deletions packages/sandbox/src/core/compartment/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ type CompartmentGlobalId = `${typeof compartmentGlobalIdPrefix}${string}${typeof

declare global {
interface Window {
__compartment_window__?: Window;

[p: CompartmentGlobalId]: WindowProxy | undefined;
}
}
Expand Down
19 changes: 4 additions & 15 deletions packages/sandbox/src/core/sandbox/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,6 @@ import type { Sandbox } from './types';
export type { Sandbox };

/**
* 生成应用运行时沙箱
*
* 沙箱分两个类型:
* 1. app 环境沙箱
* app 环境沙箱是指应用初始化过之后,应用会在什么样的上下文环境运行。每个应用的环境沙箱只会初始化一次,因为子应用只会触发一次 bootstrap 。
* 子应用在切换时,实际上切换的是 app 环境沙箱。
* 2. render 沙箱
* 子应用在 app mount 开始前生成好的的沙箱。每次子应用切换过后,render 沙箱都会重现初始化。
*
* 这么设计的目的是为了保证每个子应用切换回来之后,还能运行在应用 bootstrap 之后的环境下。
*
* @param appName
* @param getContainer
* @param opts
Expand Down Expand Up @@ -60,7 +49,7 @@ export function createSandboxContainer(
* 可能是从 bootstrap 状态进入的 mount
* 也可能是从 unmount 之后再次唤醒进入 mount
*/
async mount() {
async mount(container: HTMLElement) {
/* ------------------------------------------ 因为有上下文依赖(window),以下代码执行顺序不能变 ------------------------------------------ */

/* ------------------------------------------ 1. 启动/恢复 沙箱------------------------------------------ */
Expand All @@ -72,19 +61,19 @@ export function createSandboxContainer(
// must rebuild the side effects which added at bootstrapping firstly to recovery to nature state
if (sideEffectsRebuildsAtBootstrapping.length) {
for (const rebuildSideEffects of sideEffectsRebuildsAtBootstrapping) {
await rebuildSideEffects();
await rebuildSideEffects(container);
}
}

/* ------------------------------------------ 2. 开启全局变量补丁 ------------------------------------------*/
// render 沙箱启动时开始劫持各类全局监听,尽量不要在应用初始化阶段有 事件监听/定时器 等副作用
mountingFrees = patchAtMounting(appName, getContainer, { sandbox, ...sandboxCfg });

/* ------------------------------------------ 3. 重置一些初始化时的副作用 ------------------------------------------*/
/* ------------------------------------------ 3. 重置一些初始化时的副作用 ------------------------------------*/
// 存在 rebuilds 则表明有些副作用需要重建
if (sideEffectsRebuildsAtMounting.length) {
for (const rebuildSideEffects of sideEffectsRebuildsAtMounting) {
await rebuildSideEffects();
await rebuildSideEffects(container);
}
}

Expand Down
2 changes: 2 additions & 0 deletions packages/sandbox/src/core/sandbox/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ export interface Sandbox extends Compartment {

inactive(): void;

destroy(): void;

addIntrinsics: (intrinsics: Record<string, PropertyDescriptor>) => void;

// TODO for gc
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ declare global {
}

interface Window {
__sandboxConfigWeakMap__?: WeakMap<Sandbox, SandboxConfig>;
__currentLockingSandbox__?: Sandbox;
}

Expand All @@ -49,9 +48,7 @@ Object.defineProperty(nativeGlobal, '__currentLockingSandbox__', {
configurable: true,
});

// Share sandboxConfigWeakMap between multiple qiankun instance, thus they could access the same record
nativeGlobal.__sandboxConfigWeakMap__ = nativeGlobal.__sandboxConfigWeakMap__ || new WeakMap<Sandbox, SandboxConfig>();
const sandboxConfigWeakMap = nativeGlobal.__sandboxConfigWeakMap__;
const sandboxConfigWeakMap = new WeakMap<Sandbox, SandboxConfig>();

const elementAttachSandboxConfigMap = new WeakMap<HTMLElement, SandboxConfig>();
const patchCacheWeakMap = new WeakMap<object, unknown>();
Expand Down Expand Up @@ -356,8 +353,7 @@ export function patchStandardSandbox(

// As now the sub app content all wrapped with a special id container,
// the dynamic style sheet could be removed automatically while unmounting
return async function rebuild() {
const container = getContainer();
return async function rebuild(container: HTMLElement) {
const isElementExisted = (element: HTMLStyleElement | HTMLLinkElement) => {
if (container.contains(element)) return true;
if ('rel' in element && element.rel === 'stylesheet' && element.href)
Expand Down
2 changes: 1 addition & 1 deletion packages/sandbox/src/patchers/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@
* @author Kuitos
* @since 2023-05-04
*/
export type Rebuild = () => Promise<void>;
export type Rebuild = (container: HTMLElement) => Promise<void>;
export type Free = () => Rebuild;
export type Patch = () => Free;

0 comments on commit e5bc69e

Please sign in to comment.