✨ record latest set property to use to fallback in some incompatible scenario (#1056)
This commit is contained in:
parent
3c40e1b9ad
commit
44726a22b6
|
|
@ -115,6 +115,8 @@ export interface SandBox {
|
||||||
proxy: WindowProxy;
|
proxy: WindowProxy;
|
||||||
/** 沙箱是否在运行中 */
|
/** 沙箱是否在运行中 */
|
||||||
sandboxRunning: boolean;
|
sandboxRunning: boolean;
|
||||||
|
/** latest set property */
|
||||||
|
latestSetProp?: PropertyKey | null;
|
||||||
/** 启动沙箱 */
|
/** 启动沙箱 */
|
||||||
active(): void;
|
active(): void;
|
||||||
/** 关闭沙箱 */
|
/** 关闭沙箱 */
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ import { LifeCycles, ParcelConfigObject } from 'single-spa';
|
||||||
import getAddOns from './addons';
|
import getAddOns from './addons';
|
||||||
import { getMicroAppStateActions } from './globalState';
|
import { getMicroAppStateActions } from './globalState';
|
||||||
import { FrameworkConfiguration, FrameworkLifeCycles, HTMLContentRender, LifeCycleFn, LoadableApp } from './interfaces';
|
import { FrameworkConfiguration, FrameworkLifeCycles, HTMLContentRender, LifeCycleFn, LoadableApp } from './interfaces';
|
||||||
import { createSandbox, css } from './sandbox';
|
import { createSandboxContainer, css } from './sandbox';
|
||||||
import {
|
import {
|
||||||
Deferred,
|
Deferred,
|
||||||
getContainer,
|
getContainer,
|
||||||
|
|
@ -53,6 +53,7 @@ async function validateSingularMode<T extends object>(
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const supportShadowDOM = document.head.attachShadow || document.head.createShadowRoot;
|
const supportShadowDOM = document.head.attachShadow || document.head.createShadowRoot;
|
||||||
|
|
||||||
function createElement(
|
function createElement(
|
||||||
appContent: string,
|
appContent: string,
|
||||||
strictStyleIsolation: boolean,
|
strictStyleIsolation: boolean,
|
||||||
|
|
@ -199,11 +200,24 @@ function getRender(appName: string, appContent: string, legacyRender?: HTMLConte
|
||||||
return render;
|
return render;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getLifecyclesFromExports(scriptExports: LifeCycles<any>, appName: string, global: WindowProxy) {
|
function getLifecyclesFromExports(
|
||||||
|
scriptExports: LifeCycles<any>,
|
||||||
|
appName: string,
|
||||||
|
global: WindowProxy,
|
||||||
|
globalLatestSetProp?: PropertyKey | null,
|
||||||
|
) {
|
||||||
if (validateExportLifecycle(scriptExports)) {
|
if (validateExportLifecycle(scriptExports)) {
|
||||||
return scriptExports;
|
return scriptExports;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// fallback to sandbox latest set property if it had
|
||||||
|
if (globalLatestSetProp) {
|
||||||
|
const lifecycles = (<any>global)[globalLatestSetProp];
|
||||||
|
if (validateExportLifecycle(lifecycles)) {
|
||||||
|
return lifecycles;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (process.env.NODE_ENV === 'development') {
|
if (process.env.NODE_ENV === 'development') {
|
||||||
console.warn(
|
console.warn(
|
||||||
`[qiankun] lifecycle not found from ${appName} entry exports, fallback to get from window['${appName}']`,
|
`[qiankun] lifecycle not found from ${appName} entry exports, fallback to get from window['${appName}']`,
|
||||||
|
|
@ -223,6 +237,7 @@ function getLifecyclesFromExports(scriptExports: LifeCycles<any>, appName: strin
|
||||||
let prevAppUnmountedDeferred: Deferred<void>;
|
let prevAppUnmountedDeferred: Deferred<void>;
|
||||||
|
|
||||||
export type ParcelConfigObjectGetter = (remountContainer?: string | HTMLElement) => ParcelConfigObject;
|
export type ParcelConfigObjectGetter = (remountContainer?: string | HTMLElement) => ParcelConfigObject;
|
||||||
|
|
||||||
export async function loadApp<T extends object>(
|
export async function loadApp<T extends object>(
|
||||||
app: LoadableApp<T>,
|
app: LoadableApp<T>,
|
||||||
configuration: FrameworkConfiguration = {},
|
configuration: FrameworkConfiguration = {},
|
||||||
|
|
@ -281,8 +296,9 @@ export async function loadApp<T extends object>(
|
||||||
let mountSandbox = () => Promise.resolve();
|
let mountSandbox = () => Promise.resolve();
|
||||||
let unmountSandbox = () => Promise.resolve();
|
let unmountSandbox = () => Promise.resolve();
|
||||||
const useLooseSandbox = typeof sandbox === 'object' && !!sandbox.loose;
|
const useLooseSandbox = typeof sandbox === 'object' && !!sandbox.loose;
|
||||||
|
let sandboxContainer;
|
||||||
if (sandbox) {
|
if (sandbox) {
|
||||||
const sandboxInstance = createSandbox(
|
sandboxContainer = createSandboxContainer(
|
||||||
appName,
|
appName,
|
||||||
// FIXME should use a strict sandbox logic while remount, see https://github.com/umijs/qiankun/issues/518
|
// FIXME should use a strict sandbox logic while remount, see https://github.com/umijs/qiankun/issues/518
|
||||||
initialAppWrapperGetter,
|
initialAppWrapperGetter,
|
||||||
|
|
@ -291,9 +307,9 @@ export async function loadApp<T extends object>(
|
||||||
excludeAssetFilter,
|
excludeAssetFilter,
|
||||||
);
|
);
|
||||||
// 用沙箱的代理对象作为接下来使用的全局对象
|
// 用沙箱的代理对象作为接下来使用的全局对象
|
||||||
global = sandboxInstance.proxy as typeof window;
|
global = sandboxContainer.instance.proxy as typeof window;
|
||||||
mountSandbox = sandboxInstance.mount;
|
mountSandbox = sandboxContainer.mount;
|
||||||
unmountSandbox = sandboxInstance.unmount;
|
unmountSandbox = sandboxContainer.unmount;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { beforeUnmount = [], afterUnmount = [], afterMount = [], beforeMount = [], beforeLoad = [] } = mergeWith(
|
const { beforeUnmount = [], afterUnmount = [], afterMount = [], beforeMount = [], beforeLoad = [] } = mergeWith(
|
||||||
|
|
@ -307,7 +323,12 @@ export async function loadApp<T extends object>(
|
||||||
|
|
||||||
// get the lifecycle hooks from module exports
|
// get the lifecycle hooks from module exports
|
||||||
const scriptExports: any = await execScripts(global, !useLooseSandbox);
|
const scriptExports: any = await execScripts(global, !useLooseSandbox);
|
||||||
const { bootstrap, mount, unmount, update } = getLifecyclesFromExports(scriptExports, appName, global);
|
const { bootstrap, mount, unmount, update } = getLifecyclesFromExports(
|
||||||
|
scriptExports,
|
||||||
|
appName,
|
||||||
|
global,
|
||||||
|
sandboxContainer?.instance?.latestSetProp,
|
||||||
|
);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
onGlobalStateChange,
|
onGlobalStateChange,
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ export { css } from './patchers';
|
||||||
* @param useLooseSandbox
|
* @param useLooseSandbox
|
||||||
* @param excludeAssetFilter
|
* @param excludeAssetFilter
|
||||||
*/
|
*/
|
||||||
export function createSandbox(
|
export function createSandboxContainer(
|
||||||
appName: string,
|
appName: string,
|
||||||
elementGetter: () => HTMLElement | ShadowRoot,
|
elementGetter: () => HTMLElement | ShadowRoot,
|
||||||
scopedCSS: boolean,
|
scopedCSS: boolean,
|
||||||
|
|
@ -50,7 +50,7 @@ export function createSandbox(
|
||||||
let sideEffectsRebuilders: Rebuilder[] = [];
|
let sideEffectsRebuilders: Rebuilder[] = [];
|
||||||
|
|
||||||
return {
|
return {
|
||||||
proxy: sandbox.proxy,
|
instance: sandbox,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 沙箱被 mount
|
* 沙箱被 mount
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,8 @@ export default class SingularProxySandbox implements SandBox {
|
||||||
|
|
||||||
sandboxRunning = true;
|
sandboxRunning = true;
|
||||||
|
|
||||||
|
latestSetProp: PropertyKey | null = null;
|
||||||
|
|
||||||
active() {
|
active() {
|
||||||
if (!this.sandboxRunning) {
|
if (!this.sandboxRunning) {
|
||||||
this.currentUpdatedPropsValueMap.forEach((v, p) => setWindowProp(p, v));
|
this.currentUpdatedPropsValueMap.forEach((v, p) => setWindowProp(p, v));
|
||||||
|
|
@ -90,6 +92,8 @@ export default class SingularProxySandbox implements SandBox {
|
||||||
// eslint-disable-next-line no-param-reassign
|
// eslint-disable-next-line no-param-reassign
|
||||||
(rawWindow as any)[p] = value;
|
(rawWindow as any)[p] = value;
|
||||||
|
|
||||||
|
self.latestSetProp = p;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -136,6 +136,8 @@ export default class ProxySandbox implements SandBox {
|
||||||
|
|
||||||
sandboxRunning = true;
|
sandboxRunning = true;
|
||||||
|
|
||||||
|
latestSetProp: PropertyKey | null = null;
|
||||||
|
|
||||||
active() {
|
active() {
|
||||||
if (!this.sandboxRunning) activeSandboxCount++;
|
if (!this.sandboxRunning) activeSandboxCount++;
|
||||||
this.sandboxRunning = true;
|
this.sandboxRunning = true;
|
||||||
|
|
@ -199,6 +201,8 @@ export default class ProxySandbox implements SandBox {
|
||||||
|
|
||||||
updatedValueSet.add(p);
|
updatedValueSet.add(p);
|
||||||
|
|
||||||
|
self.latestSetProp = p;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user