✨ enable speedy sandbox mode by default (#2320)
This commit is contained in:
parent
6544b17f9b
commit
743473ae51
|
|
@ -11,8 +11,9 @@ writeFileSync(versionFilePath, `export const version = '${version}';`);
|
||||||
const globalsFilePath = join(__dirname, './src/sandbox/globals.ts');
|
const globalsFilePath = join(__dirname, './src/sandbox/globals.ts');
|
||||||
writeFileSync(
|
writeFileSync(
|
||||||
globalsFilePath,
|
globalsFilePath,
|
||||||
`// generated from https://github.com/sindresorhus/globals/blob/main/globals.json builtin part
|
`// generated from https://github.com/sindresorhus/globals/blob/main/globals.json es2015 part
|
||||||
export const globals = ${JSON.stringify(Object.keys(globals.builtin), null, 2)};`,
|
// only init its values while Proxy is supported
|
||||||
|
export const globals = window.Proxy ? ${JSON.stringify(Object.keys(globals.es2015), null, 2)} : [];`,
|
||||||
);
|
);
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|
|
||||||
|
|
@ -75,6 +75,9 @@ type QiankunSpecialOpts = {
|
||||||
* @deprecated We use strict mode by default
|
* @deprecated We use strict mode by default
|
||||||
*/
|
*/
|
||||||
loose?: boolean;
|
loose?: boolean;
|
||||||
|
/**
|
||||||
|
* use speed sandbox mode, enabled by default from 2.9.0
|
||||||
|
*/
|
||||||
speedy?: boolean;
|
speedy?: boolean;
|
||||||
patchers?: Patcher[];
|
patchers?: Patcher[];
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ import type {
|
||||||
ObjectType,
|
ObjectType,
|
||||||
} from './interfaces';
|
} from './interfaces';
|
||||||
import { createSandboxContainer, css } from './sandbox';
|
import { createSandboxContainer, css } from './sandbox';
|
||||||
import { lexicalGlobals } from './sandbox/common';
|
import { trustedGlobals } from './sandbox/common';
|
||||||
import {
|
import {
|
||||||
Deferred,
|
Deferred,
|
||||||
genAppInstanceIdByName,
|
genAppInstanceIdByName,
|
||||||
|
|
@ -311,7 +311,8 @@ export async function loadApp<T extends ObjectType>(
|
||||||
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;
|
||||||
const speedySandbox = typeof sandbox === 'object' && !!sandbox.speedy;
|
// enable speedy mode by default
|
||||||
|
const speedySandbox = typeof sandbox === 'object' ? sandbox.speedy !== false : true;
|
||||||
let sandboxContainer;
|
let sandboxContainer;
|
||||||
if (sandbox) {
|
if (sandbox) {
|
||||||
sandboxContainer = createSandboxContainer(
|
sandboxContainer = createSandboxContainer(
|
||||||
|
|
@ -342,7 +343,7 @@ export async function loadApp<T extends ObjectType>(
|
||||||
|
|
||||||
// get the lifecycle hooks from module exports
|
// get the lifecycle hooks from module exports
|
||||||
const scriptExports: any = await execScripts(global, sandbox && !useLooseSandbox, {
|
const scriptExports: any = await execScripts(global, sandbox && !useLooseSandbox, {
|
||||||
scopedGlobalVariables: speedySandbox ? lexicalGlobals : [],
|
scopedGlobalVariables: speedySandbox ? trustedGlobals : [],
|
||||||
});
|
});
|
||||||
const { bootstrap, mount, unmount, update } = getLifecyclesFromExports(
|
const { bootstrap, mount, unmount, update } = getLifecyclesFromExports(
|
||||||
scriptExports,
|
scriptExports,
|
||||||
|
|
|
||||||
|
|
@ -18,13 +18,12 @@ export function getCurrentRunningApp() {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function setCurrentRunningApp(appInstance: { name: string; window: WindowProxy } | null) {
|
export function setCurrentRunningApp(appInstance: { name: string; window: WindowProxy } | null) {
|
||||||
// set currentRunningApp and it's proxySandbox to global window, as its only use case is for document.createElement from now on, which hijacked by a global way
|
// Set currentRunningApp and it's proxySandbox to global window, as its only use case is for document.createElement from now on, which hijacked by a global way
|
||||||
currentRunningApp = appInstance;
|
currentRunningApp = appInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
const scopedGlobals = ['window', 'self', 'globalThis', 'top', 'parent', 'hasOwnProperty', 'document', 'eval'];
|
const spiedGlobals = ['window', 'self', 'globalThis', 'top', 'parent', 'hasOwnProperty', 'document', 'eval'];
|
||||||
export const unscopedGlobals = [...without(globals, ...scopedGlobals), 'requestAnimationFrame'];
|
export const trustedGlobals = [...without(globals, ...spiedGlobals), 'requestAnimationFrame'];
|
||||||
export const lexicalGlobals = [...unscopedGlobals, ...scopedGlobals];
|
|
||||||
|
|
||||||
const functionBoundedValueMap = new WeakMap<CallableFunction, CallableFunction>();
|
const functionBoundedValueMap = new WeakMap<CallableFunction, CallableFunction>();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,69 +1,63 @@
|
||||||
// generated from https://github.com/sindresorhus/globals/blob/main/globals.json builtin part
|
// generated from https://github.com/sindresorhus/globals/blob/main/globals.json es2015 part
|
||||||
export const globals = [
|
// only init its values while Proxy is supported
|
||||||
'AggregateError',
|
export const globals = window.Proxy
|
||||||
'Array',
|
? [
|
||||||
'ArrayBuffer',
|
'Array',
|
||||||
'Atomics',
|
'ArrayBuffer',
|
||||||
'BigInt',
|
'Boolean',
|
||||||
'BigInt64Array',
|
'constructor',
|
||||||
'BigUint64Array',
|
'DataView',
|
||||||
'Boolean',
|
'Date',
|
||||||
'constructor',
|
'decodeURI',
|
||||||
'DataView',
|
'decodeURIComponent',
|
||||||
'Date',
|
'encodeURI',
|
||||||
'decodeURI',
|
'encodeURIComponent',
|
||||||
'decodeURIComponent',
|
'Error',
|
||||||
'encodeURI',
|
'escape',
|
||||||
'encodeURIComponent',
|
'eval',
|
||||||
'Error',
|
'EvalError',
|
||||||
'escape',
|
'Float32Array',
|
||||||
'eval',
|
'Float64Array',
|
||||||
'EvalError',
|
'Function',
|
||||||
'FinalizationRegistry',
|
'hasOwnProperty',
|
||||||
'Float32Array',
|
'Infinity',
|
||||||
'Float64Array',
|
'Int16Array',
|
||||||
'Function',
|
'Int32Array',
|
||||||
'globalThis',
|
'Int8Array',
|
||||||
'hasOwnProperty',
|
'isFinite',
|
||||||
'Infinity',
|
'isNaN',
|
||||||
'Int16Array',
|
'isPrototypeOf',
|
||||||
'Int32Array',
|
'JSON',
|
||||||
'Int8Array',
|
'Map',
|
||||||
'isFinite',
|
'Math',
|
||||||
'isNaN',
|
'NaN',
|
||||||
'isPrototypeOf',
|
'Number',
|
||||||
'JSON',
|
'Object',
|
||||||
'Map',
|
'parseFloat',
|
||||||
'Math',
|
'parseInt',
|
||||||
'NaN',
|
'Promise',
|
||||||
'Number',
|
'propertyIsEnumerable',
|
||||||
'Object',
|
'Proxy',
|
||||||
'parseFloat',
|
'RangeError',
|
||||||
'parseInt',
|
'ReferenceError',
|
||||||
'Promise',
|
'Reflect',
|
||||||
'propertyIsEnumerable',
|
'RegExp',
|
||||||
'Proxy',
|
'Set',
|
||||||
'RangeError',
|
'String',
|
||||||
'ReferenceError',
|
'Symbol',
|
||||||
'Reflect',
|
'SyntaxError',
|
||||||
'RegExp',
|
'toLocaleString',
|
||||||
'Set',
|
'toString',
|
||||||
'SharedArrayBuffer',
|
'TypeError',
|
||||||
'String',
|
'Uint16Array',
|
||||||
'Symbol',
|
'Uint32Array',
|
||||||
'SyntaxError',
|
'Uint8Array',
|
||||||
'toLocaleString',
|
'Uint8ClampedArray',
|
||||||
'toString',
|
'undefined',
|
||||||
'TypeError',
|
'unescape',
|
||||||
'Uint16Array',
|
'URIError',
|
||||||
'Uint32Array',
|
'valueOf',
|
||||||
'Uint8Array',
|
'WeakMap',
|
||||||
'Uint8ClampedArray',
|
'WeakSet',
|
||||||
'undefined',
|
]
|
||||||
'unescape',
|
: [];
|
||||||
'URIError',
|
|
||||||
'valueOf',
|
|
||||||
'WeakMap',
|
|
||||||
'WeakRef',
|
|
||||||
'WeakSet',
|
|
||||||
];
|
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ import { execScripts } from 'import-html-entry';
|
||||||
import { isFunction } from 'lodash';
|
import { isFunction } from 'lodash';
|
||||||
import { frameworkConfiguration } from '../../../apis';
|
import { frameworkConfiguration } from '../../../apis';
|
||||||
import { qiankunHeadTagName } from '../../../utils';
|
import { qiankunHeadTagName } from '../../../utils';
|
||||||
import { lexicalGlobals } from '../../common';
|
import { trustedGlobals } from '../../common';
|
||||||
import * as css from '../css';
|
import * as css from '../css';
|
||||||
|
|
||||||
export const rawHeadAppendChild = HTMLHeadElement.prototype.appendChild;
|
export const rawHeadAppendChild = HTMLHeadElement.prototype.appendChild;
|
||||||
|
|
@ -280,7 +280,7 @@ function getOverwrittenAppendChildOrInsertBefore(opts: {
|
||||||
const { fetch } = frameworkConfiguration;
|
const { fetch } = frameworkConfiguration;
|
||||||
const referenceNode = mountDOM.contains(refChild) ? refChild : null;
|
const referenceNode = mountDOM.contains(refChild) ? refChild : null;
|
||||||
|
|
||||||
const scopedGlobalVariables = speedySandbox ? lexicalGlobals : [];
|
const scopedGlobalVariables = speedySandbox ? trustedGlobals : [];
|
||||||
|
|
||||||
if (src) {
|
if (src) {
|
||||||
execScripts(null, [src], proxy, {
|
execScripts(null, [src], proxy, {
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
import type { SandBox } from '../interfaces';
|
import type { SandBox } from '../interfaces';
|
||||||
import { SandBoxType } from '../interfaces';
|
import { SandBoxType } from '../interfaces';
|
||||||
import { isPropertyFrozen, nativeGlobal, nextTask } from '../utils';
|
import { isPropertyFrozen, nativeGlobal, nextTask } from '../utils';
|
||||||
import { getCurrentRunningApp, getTargetValue, setCurrentRunningApp, unscopedGlobals } from './common';
|
import { getCurrentRunningApp, getTargetValue, trustedGlobals, setCurrentRunningApp } from './common';
|
||||||
|
|
||||||
type SymbolTarget = 'target' | 'globalContext';
|
type SymbolTarget = 'target' | 'globalContext';
|
||||||
|
|
||||||
|
|
@ -49,7 +49,7 @@ const globalVariableWhiteList: string[] = [
|
||||||
variables who are impossible to be overwritten need to be escaped from proxy sandbox for performance reasons
|
variables who are impossible to be overwritten need to be escaped from proxy sandbox for performance reasons
|
||||||
see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/unscopables
|
see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/unscopables
|
||||||
*/
|
*/
|
||||||
const unscopables = unscopedGlobals.reduce((acc, key) => ({ ...acc, [key]: true }), { __proto__: null });
|
const unscopables = trustedGlobals.reduce((acc, key) => ({ ...acc, [key]: true }), { __proto__: null });
|
||||||
|
|
||||||
const useNativeWindowForBindingsProps = new Map<PropertyKey, boolean>([
|
const useNativeWindowForBindingsProps = new Map<PropertyKey, boolean>([
|
||||||
['fetch', true],
|
['fetch', true],
|
||||||
|
|
@ -132,9 +132,6 @@ export default class ProxySandbox implements SandBox {
|
||||||
sandboxRunning = true;
|
sandboxRunning = true;
|
||||||
latestSetProp: PropertyKey | null = null;
|
latestSetProp: PropertyKey | null = null;
|
||||||
|
|
||||||
// the descriptor of global variables in whitelist before it been modified
|
|
||||||
globalWhitelistPrevDescriptor: { [p in typeof globalVariableWhiteList[number]]: PropertyDescriptor | undefined } = {};
|
|
||||||
|
|
||||||
active() {
|
active() {
|
||||||
if (!this.sandboxRunning) activeSandboxCount++;
|
if (!this.sandboxRunning) activeSandboxCount++;
|
||||||
this.sandboxRunning = true;
|
this.sandboxRunning = true;
|
||||||
|
|
@ -163,6 +160,8 @@ export default class ProxySandbox implements SandBox {
|
||||||
this.sandboxRunning = false;
|
this.sandboxRunning = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// the descriptor of global variables in whitelist before it been modified
|
||||||
|
globalWhitelistPrevDescriptor: { [p in typeof globalVariableWhiteList[number]]: PropertyDescriptor | undefined } = {};
|
||||||
globalContext: typeof window;
|
globalContext: typeof window;
|
||||||
|
|
||||||
constructor(name: string, globalContext = window) {
|
constructor(name: string, globalContext = window) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user