diff --git a/src/loader.ts b/src/loader.ts index bc8334808..958655473 100644 --- a/src/loader.ts +++ b/src/loader.ts @@ -25,6 +25,7 @@ import { getContainer, getDefaultTplWrapper, getWrapperId, + isEnableProxyStyle, isEnableScopedCSS, performanceGetEntriesByName, performanceMark, @@ -285,6 +286,7 @@ export async function loadApp( } const scopedCSS = isEnableScopedCSS(sandbox); + const proxyCSS = isEnableProxyStyle(sandbox); let initialAppWrapperElement: HTMLElement | null = createElement( appContent, strictStyleIsolation, @@ -322,6 +324,7 @@ export async function loadApp( // FIXME should use a strict sandbox logic while remount, see https://github.com/umijs/qiankun/issues/518 initialAppWrapperGetter, scopedCSS, + proxyCSS, useLooseSandbox, excludeAssetFilter, global, diff --git a/src/sandbox/index.ts b/src/sandbox/index.ts index e5ad1c254..a35c51c0e 100644 --- a/src/sandbox/index.ts +++ b/src/sandbox/index.ts @@ -35,6 +35,7 @@ export function createSandboxContainer( appName: string, elementGetter: () => HTMLElement | ShadowRoot, scopedCSS: boolean, + proxyCSS: boolean, useLooseSandbox?: boolean, excludeAssetFilter?: (url: string) => boolean, globalContext?: typeof window, @@ -55,6 +56,7 @@ export function createSandboxContainer( elementGetter, sandbox, scopedCSS, + proxyCSS, excludeAssetFilter, speedySandBox, ); @@ -87,7 +89,15 @@ export function createSandboxContainer( /* ------------------------------------------ 2. 开启全局变量补丁 ------------------------------------------*/ // render 沙箱启动时开始劫持各类全局监听,尽量不要在应用初始化阶段有 事件监听/定时器 等副作用 - mountingFreers = patchAtMounting(appName, elementGetter, sandbox, scopedCSS, excludeAssetFilter, speedySandBox); + mountingFreers = patchAtMounting( + appName, + elementGetter, + sandbox, + scopedCSS, + proxyCSS, + excludeAssetFilter, + speedySandBox, + ); /* ------------------------------------------ 3. 重置一些初始化时的副作用 ------------------------------------------*/ // 存在 rebuilder 则表明有些副作用需要重建 diff --git a/src/sandbox/patchers/dynamicAppend/__tests__/forStrictSandbox.test.ts b/src/sandbox/patchers/dynamicAppend/__tests__/forStrictSandbox.test.ts index 54512c14f..32ff12825 100644 --- a/src/sandbox/patchers/dynamicAppend/__tests__/forStrictSandbox.test.ts +++ b/src/sandbox/patchers/dynamicAppend/__tests__/forStrictSandbox.test.ts @@ -45,7 +45,7 @@ describe('forStrictSandbox test', () => { active: noop, inactive: noop, }; - patchStrictSandbox(appName, () => wrapper, sandbox, true, false, undefined, true); + patchStrictSandbox(appName, () => wrapper, sandbox, true, false, true, undefined, true); expect(patchedDocument).toBeDefined(); expect(() => patchedDocument?.createTreeWalker(patchedDocument)).not.toThrow(); diff --git a/src/sandbox/patchers/dynamicAppend/common.ts b/src/sandbox/patchers/dynamicAppend/common.ts index 221d5f21c..e6a950eea 100644 --- a/src/sandbox/patchers/dynamicAppend/common.ts +++ b/src/sandbox/patchers/dynamicAppend/common.ts @@ -188,6 +188,7 @@ export type ContainerConfig = { dynamicStyleSheetElements: Array; appWrapperGetter: CallableFunction; scopedCSS: boolean; + proxyCSS: boolean; excludeAssetFilter?: CallableFunction; }; @@ -218,6 +219,7 @@ function getOverwrittenAppendChildOrInsertBefore(opts: { speedySandbox, dynamicStyleSheetElements, scopedCSS, + proxyCSS, excludeAssetFilter, } = containerConfig; @@ -258,6 +260,20 @@ function getOverwrittenAppendChildOrInsertBefore(opts: { } else { css.process(appWrapper, stylesheetElement, appName); } + } else if (proxyCSS) { + // exclude link elements like + const linkElementUsingStylesheet = + element.tagName?.toUpperCase() === LINK_TAG_NAME && + (element as HTMLLinkElement).rel === 'stylesheet' && + (element as HTMLLinkElement).href; + if (linkElementUsingStylesheet) { + const fetch = + typeof frameworkConfiguration.fetch === 'function' + ? frameworkConfiguration.fetch + : frameworkConfiguration.fetch?.fn; + stylesheetElement = convertLinkAsStyle(element, () => {}, fetch); + dynamicLinkAttachedInlineStyleMap.set(element, stylesheetElement); + } } const mountDOM = target === 'head' ? getAppWrapperHeadElement(appWrapper) : appWrapper; diff --git a/src/sandbox/patchers/dynamicAppend/forLooseSandbox.ts b/src/sandbox/patchers/dynamicAppend/forLooseSandbox.ts index 48abb6e60..b5d5e547a 100644 --- a/src/sandbox/patchers/dynamicAppend/forLooseSandbox.ts +++ b/src/sandbox/patchers/dynamicAppend/forLooseSandbox.ts @@ -30,6 +30,7 @@ export function patchLooseSandbox( sandbox: SandBox, mounting = true, scopedCSS = false, + proxyCSS = true, excludeAssetFilter?: CallableFunction, ): Freer { const { proxy } = sandbox; @@ -53,6 +54,7 @@ export function patchLooseSandbox( strictGlobal: false, speedySandbox: false, scopedCSS, + proxyCSS, dynamicStyleSheetElements, excludeAssetFilter, }), diff --git a/src/sandbox/patchers/dynamicAppend/forStrictSandbox.ts b/src/sandbox/patchers/dynamicAppend/forStrictSandbox.ts index 34ba27680..a574134d4 100644 --- a/src/sandbox/patchers/dynamicAppend/forStrictSandbox.ts +++ b/src/sandbox/patchers/dynamicAppend/forStrictSandbox.ts @@ -227,6 +227,7 @@ export function patchStrictSandbox( sandbox: SandBox, mounting = true, scopedCSS = false, + proxyCSS = true, excludeAssetFilter?: CallableFunction, speedySandbox = false, ): Freer { @@ -242,6 +243,7 @@ export function patchStrictSandbox( speedySandbox, excludeAssetFilter, scopedCSS, + proxyCSS, }; proxyAttachContainerConfigMap.set(proxy, containerConfig); } diff --git a/src/sandbox/patchers/index.ts b/src/sandbox/patchers/index.ts index 34827a6dd..28f0ff24c 100644 --- a/src/sandbox/patchers/index.ts +++ b/src/sandbox/patchers/index.ts @@ -16,6 +16,7 @@ export function patchAtMounting( elementGetter: () => HTMLElement | ShadowRoot, sandbox: SandBox, scopedCSS: boolean, + proxyCSS: boolean, excludeAssetFilter?: CallableFunction, speedySandBox?: boolean, ): Freer[] { @@ -28,15 +29,25 @@ export function patchAtMounting( const patchersInSandbox = { [SandBoxType.LegacyProxy]: [ ...basePatchers, - () => patchLooseSandbox(appName, elementGetter, sandbox, true, scopedCSS, excludeAssetFilter), + () => patchLooseSandbox(appName, elementGetter, sandbox, true, scopedCSS, proxyCSS, excludeAssetFilter), ], [SandBoxType.Proxy]: [ ...basePatchers, - () => patchStrictSandbox(appName, elementGetter, sandbox, true, scopedCSS, excludeAssetFilter, speedySandBox), + () => + patchStrictSandbox( + appName, + elementGetter, + sandbox, + true, + scopedCSS, + proxyCSS, + excludeAssetFilter, + speedySandBox, + ), ], [SandBoxType.Snapshot]: [ ...basePatchers, - () => patchLooseSandbox(appName, elementGetter, sandbox, true, scopedCSS, excludeAssetFilter), + () => patchLooseSandbox(appName, elementGetter, sandbox, true, scopedCSS, proxyCSS, excludeAssetFilter), ], }; @@ -48,18 +59,29 @@ export function patchAtBootstrapping( elementGetter: () => HTMLElement | ShadowRoot, sandbox: SandBox, scopedCSS: boolean, + proxyCSS: boolean, excludeAssetFilter?: CallableFunction, speedySandBox?: boolean, ): Freer[] { const patchersInSandbox = { [SandBoxType.LegacyProxy]: [ - () => patchLooseSandbox(appName, elementGetter, sandbox, false, scopedCSS, excludeAssetFilter), + () => patchLooseSandbox(appName, elementGetter, sandbox, false, scopedCSS, proxyCSS, excludeAssetFilter), ], [SandBoxType.Proxy]: [ - () => patchStrictSandbox(appName, elementGetter, sandbox, false, scopedCSS, excludeAssetFilter, speedySandBox), + () => + patchStrictSandbox( + appName, + elementGetter, + sandbox, + false, + scopedCSS, + proxyCSS, + excludeAssetFilter, + speedySandBox, + ), ], [SandBoxType.Snapshot]: [ - () => patchLooseSandbox(appName, elementGetter, sandbox, false, scopedCSS, excludeAssetFilter), + () => patchLooseSandbox(appName, elementGetter, sandbox, false, scopedCSS, proxyCSS, excludeAssetFilter), ], }; diff --git a/src/utils.ts b/src/utils.ts index 0da6841f2..426ad6191 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -262,6 +262,18 @@ export function isEnableScopedCSS(sandbox: FrameworkConfiguration['sandbox']) { return !!sandbox.experimentalStyleIsolation; } +export function isEnableProxyStyle(sandbox: FrameworkConfiguration['sandbox']) { + if (typeof sandbox !== 'object') { + return false; + } + + if (sandbox.strictStyleIsolation) { + return false; + } + + return true; +} + /** * copy from https://developer.mozilla.org/zh-CN/docs/Using_XPath * @param el diff --git a/src/version.ts b/src/version.ts index a7250834f..059ef8651 100644 --- a/src/version.ts +++ b/src/version.ts @@ -1 +1 @@ -export { version } from '../package.json'; +export const version = '2.10.9';