From 44ccad92de758093a2b3f702bfe8a54e3abc064a Mon Sep 17 00:00:00 2001 From: Kuitos Date: Mon, 2 Aug 2021 21:04:28 +0800 Subject: [PATCH] =?UTF-8?q?=E2=9A=A1=EF=B8=8F=20fix=20the=20performance=20?= =?UTF-8?q?issue=20in=20sandbox=20(#1626)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/sandbox/common.ts | 16 +++++++++++++--- src/sandbox/proxySandbox.ts | 4 ++-- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/sandbox/common.ts b/src/sandbox/common.ts index 6a1fd21..681fb1a 100644 --- a/src/sandbox/common.ts +++ b/src/sandbox/common.ts @@ -5,13 +5,23 @@ import { isBoundedFunction, isCallable, isConstructable } from '../utils'; -let currentRunningSandboxProxy: WindowProxy | null = null; +declare global { + interface Window { + __currentRunningSandboxProxy__: WindowProxy | null; + } +} + +// Get native global window with a sandbox disgusted way, thus we could share it between qiankun instances🤪 +// eslint-disable-next-line no-new-func +const nativeGlobal: Window = new Function('return this')(); +Object.defineProperty(nativeGlobal, '__currentRunningSandboxProxy__', { enumerable: false, writable: true }); export function getCurrentRunningSandboxProxy() { - return currentRunningSandboxProxy; + return nativeGlobal.__currentRunningSandboxProxy__; } export function setCurrentRunningSandboxProxy(proxy: WindowProxy | null) { - currentRunningSandboxProxy = proxy; + // set currentRunningSandboxProxy to global window, as its only use case is for document.createElement from now on, which hijacked by a global way + nativeGlobal.__currentRunningSandboxProxy__ = proxy; } const functionBoundedValueMap = new WeakMap(); diff --git a/src/sandbox/proxySandbox.ts b/src/sandbox/proxySandbox.ts index 6b679e0..db8c61d 100644 --- a/src/sandbox/proxySandbox.ts +++ b/src/sandbox/proxySandbox.ts @@ -215,14 +215,14 @@ export default class ProxySandbox implements SandBox { }, get(target: FakeWindow, p: PropertyKey): any { + if (p === Symbol.unscopables) return unscopables; + setCurrentRunningSandboxProxy(proxy); // FIXME if you have any other good ideas // remove the mark in next tick, thus we can identify whether it in micro app or not // this approach is just a workaround, it could not cover all complex cases, such as the micro app runs in the same task context with master in some case nextTick(() => setCurrentRunningSandboxProxy(null)); - if (p === Symbol.unscopables) return unscopables; - // avoid who using window.window or window.self to escape the sandbox environment to touch the really window // see https://github.com/eligrey/FileSaver.js/blob/master/src/FileSaver.js#L13 if (p === 'window' || p === 'self') {