From 28427aba370bdf127aaf2514c4b7172ccd1037d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=98=93=E7=90=A6?= Date: Thu, 21 May 2020 13:17:17 +0800 Subject: [PATCH 1/6] =?UTF-8?q?feat:=20insertBefore=E5=8A=A0=E5=85=A5scrip?= =?UTF-8?q?t=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/sandbox/patchers/dynamicHeadAppend.ts | 42 ++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/src/sandbox/patchers/dynamicHeadAppend.ts b/src/sandbox/patchers/dynamicHeadAppend.ts index 3454945f3..76ec7901a 100644 --- a/src/sandbox/patchers/dynamicHeadAppend.ts +++ b/src/sandbox/patchers/dynamicHeadAppend.ts @@ -179,7 +179,7 @@ function getNewInsertBefore(...args: any[]) { const element = newChild as any; if (element.tagName) { // eslint-disable-next-line prefer-const - let [appName, appWrapperGetter, singular, dynamicStyleSheetElements] = args; + let [appName, appWrapperGetter, proxy, singular, dynamicStyleSheetElements] = args; const storedContainerInfo = element[attachProxySymbol]; if (storedContainerInfo) { @@ -215,6 +215,45 @@ function getNewInsertBefore(...args: any[]) { return rawHeadInsertBefore.call(this, element, refChild) as T; } + case SCRIPT_TAG_NAME: { + const { src, text } = element as HTMLScriptElement; + + const { fetch } = frameworkConfiguration; + if (src) { + execScripts(null, [src], proxy, { fetch, strictGlobal: !singular }).then( + () => { + // we need to invoke the onload event manually to notify the event listener that the script was completed + // here are the two typical ways of dynamic script loading + // 1. element.onload callback way, which webpack and loadjs used, see https://github.com/muicss/loadjs/blob/master/src/loadjs.js#L138 + // 2. addEventListener way, which toast-loader used, see https://github.com/pyrsmk/toast/blob/master/src/Toast.ts#L64 + const loadEvent = new CustomEvent('load'); + if (isFunction(element.onload)) { + element.onload(loadEvent); + } else { + element.dispatchEvent(loadEvent); + } + }, + () => { + const errorEvent = new CustomEvent('error'); + if (isFunction(element.onerror)) { + element.onerror(errorEvent); + } else { + element.dispatchEvent(errorEvent); + } + }, + ); + + const dynamicScriptCommentElement = document.createComment(`dynamic script ${src} replaced by qiankun`); + return rawAppendChild.call(appWrapperGetter(), dynamicScriptCommentElement) as T; + } + + execScripts(null, [``], proxy, { strictGlobal: !singular }).then( + element.onload, + element.onerror, + ); + const dynamicInlineScriptCommentElement = document.createComment('dynamic inline script replaced by qiankun'); + return rawAppendChild.call(appWrapperGetter(), dynamicInlineScriptCommentElement) as T; + } default: break; } @@ -298,6 +337,7 @@ export default function patch( HTMLHeadElement.prototype.insertBefore = getNewInsertBefore( appName, appWrapperGetter, + proxy, singular, dynamicStyleSheetElements, ); From e91f1abc05fa8e6432673e4deadf3d649013fe53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=98=93=E7=90=A6?= Date: Thu, 21 May 2020 14:12:53 +0800 Subject: [PATCH 2/6] =?UTF-8?q?fix:=20=E6=9B=BF=E6=8D=A2rawAppendChild?= =?UTF-8?q?=E4=B8=BArawHeadInsertBefore?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/sandbox/patchers/dynamicHeadAppend.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sandbox/patchers/dynamicHeadAppend.ts b/src/sandbox/patchers/dynamicHeadAppend.ts index 76ec7901a..05353b11e 100644 --- a/src/sandbox/patchers/dynamicHeadAppend.ts +++ b/src/sandbox/patchers/dynamicHeadAppend.ts @@ -244,7 +244,7 @@ function getNewInsertBefore(...args: any[]) { ); const dynamicScriptCommentElement = document.createComment(`dynamic script ${src} replaced by qiankun`); - return rawAppendChild.call(appWrapperGetter(), dynamicScriptCommentElement) as T; + return rawHeadInsertBefore.call(appWrapperGetter(), dynamicScriptCommentElement, refChild) as T; } execScripts(null, [``], proxy, { strictGlobal: !singular }).then( @@ -252,7 +252,7 @@ function getNewInsertBefore(...args: any[]) { element.onerror, ); const dynamicInlineScriptCommentElement = document.createComment('dynamic inline script replaced by qiankun'); - return rawAppendChild.call(appWrapperGetter(), dynamicInlineScriptCommentElement) as T; + return rawHeadInsertBefore.call(appWrapperGetter(), dynamicInlineScriptCommentElement, refChild) as T; } default: break; From 04687001acdc6e916f272e2db21ddd0e4cadc1ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=98=93=E7=90=A6?= Date: Thu, 21 May 2020 19:19:47 +0800 Subject: [PATCH 3/6] =?UTF-8?q?fix:=20=E5=8A=A0=E5=85=A5refChild=E4=B8=8Ew?= =?UTF-8?q?rapper=E6=98=AF=E5=90=A6=E5=8C=85=E5=90=AB=E5=85=B3=E7=B3=BB?= =?UTF-8?q?=E7=9A=84=E5=88=A4=E6=96=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/sandbox/patchers/dynamicHeadAppend.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/sandbox/patchers/dynamicHeadAppend.ts b/src/sandbox/patchers/dynamicHeadAppend.ts index 05353b11e..6abdc3b19 100644 --- a/src/sandbox/patchers/dynamicHeadAppend.ts +++ b/src/sandbox/patchers/dynamicHeadAppend.ts @@ -219,6 +219,9 @@ function getNewInsertBefore(...args: any[]) { const { src, text } = element as HTMLScriptElement; const { fetch } = frameworkConfiguration; + const wrapper = appWrapperGetter(); + const referenceNode = wrapper.contains(refChild) ? refChild : null; + if (src) { execScripts(null, [src], proxy, { fetch, strictGlobal: !singular }).then( () => { @@ -244,7 +247,7 @@ function getNewInsertBefore(...args: any[]) { ); const dynamicScriptCommentElement = document.createComment(`dynamic script ${src} replaced by qiankun`); - return rawHeadInsertBefore.call(appWrapperGetter(), dynamicScriptCommentElement, refChild) as T; + return rawHeadInsertBefore.call(appWrapperGetter(), dynamicScriptCommentElement, referenceNode) as T; } execScripts(null, [``], proxy, { strictGlobal: !singular }).then( @@ -252,7 +255,7 @@ function getNewInsertBefore(...args: any[]) { element.onerror, ); const dynamicInlineScriptCommentElement = document.createComment('dynamic inline script replaced by qiankun'); - return rawHeadInsertBefore.call(appWrapperGetter(), dynamicInlineScriptCommentElement, refChild) as T; + return rawHeadInsertBefore.call(appWrapperGetter(), dynamicInlineScriptCommentElement, referenceNode) as T; } default: break; From 9f42b406d932d3f876f05cac9c11bb18e08afc9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=98=93=E7=90=A6?= Date: Thu, 21 May 2020 19:33:18 +0800 Subject: [PATCH 4/6] =?UTF-8?q?fix:=20=E5=8A=A0=E5=85=A5invokedByMicroApp?= =?UTF-8?q?=E5=88=A4=E6=96=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/sandbox/patchers/dynamicHeadAppend.ts | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/sandbox/patchers/dynamicHeadAppend.ts b/src/sandbox/patchers/dynamicHeadAppend.ts index 6abdc3b19..c9ce9b13f 100644 --- a/src/sandbox/patchers/dynamicHeadAppend.ts +++ b/src/sandbox/patchers/dynamicHeadAppend.ts @@ -191,6 +191,11 @@ function getNewInsertBefore(...args: any[]) { dynamicStyleSheetElements = storedContainerInfo.dynamicStyleSheetElements; } + // have storedContainerInfo means it invoked by a micro app + const invokedByMicroApp = storedContainerInfo && !singular; + const wrapper = appWrapperGetter(); + const referenceNode = wrapper.contains(refChild) ? refChild : null; + switch (element.tagName) { case LINK_TAG_NAME: case STYLE_TAG_NAME: { @@ -207,8 +212,6 @@ function getNewInsertBefore(...args: any[]) { if (activated) { dynamicStyleSheetElements.push(stylesheetElement); - const wrapper = appWrapperGetter(); - const referenceNode = wrapper.contains(refChild) ? refChild : null; return rawHeadInsertBefore.call(wrapper, stylesheetElement, referenceNode) as T; } @@ -216,11 +219,13 @@ function getNewInsertBefore(...args: any[]) { return rawHeadInsertBefore.call(this, element, refChild) as T; } case SCRIPT_TAG_NAME: { + if (!invokedByMicroApp) { + return rawHeadInsertBefore.call(this, element, referenceNode) as T; + } + const { src, text } = element as HTMLScriptElement; const { fetch } = frameworkConfiguration; - const wrapper = appWrapperGetter(); - const referenceNode = wrapper.contains(refChild) ? refChild : null; if (src) { execScripts(null, [src], proxy, { fetch, strictGlobal: !singular }).then( From 594385bf5ac54deda30f8d7ef4c81570b8663385 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=98=93=E7=90=A6?= Date: Thu, 21 May 2020 19:40:00 +0800 Subject: [PATCH 5/6] =?UTF-8?q?fix:=20=E5=8A=A0=E5=85=A5invokedByMicroApp?= =?UTF-8?q?=E5=88=A4=E6=96=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/sandbox/patchers/dynamicHeadAppend.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/sandbox/patchers/dynamicHeadAppend.ts b/src/sandbox/patchers/dynamicHeadAppend.ts index c9ce9b13f..e0c1ebcf7 100644 --- a/src/sandbox/patchers/dynamicHeadAppend.ts +++ b/src/sandbox/patchers/dynamicHeadAppend.ts @@ -194,7 +194,7 @@ function getNewInsertBefore(...args: any[]) { // have storedContainerInfo means it invoked by a micro app const invokedByMicroApp = storedContainerInfo && !singular; const wrapper = appWrapperGetter(); - const referenceNode = wrapper.contains(refChild) ? refChild : null; + let referenceNode = wrapper.contains(refChild) ? refChild : null; switch (element.tagName) { case LINK_TAG_NAME: @@ -220,6 +220,8 @@ function getNewInsertBefore(...args: any[]) { } case SCRIPT_TAG_NAME: { if (!invokedByMicroApp) { + referenceNode = this.contains(refChild) ? refChild : null; + return rawHeadInsertBefore.call(this, element, referenceNode) as T; } From 95fd2be76d5f7c2b08f6d5230d3f8fc3249bff46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=98=93=E7=90=A6?= Date: Thu, 21 May 2020 21:12:44 +0800 Subject: [PATCH 6/6] =?UTF-8?q?fix:=20=E5=8A=A0=E5=85=A5invokedByMicroApp?= =?UTF-8?q?=E5=88=A4=E6=96=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/sandbox/patchers/dynamicHeadAppend.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/sandbox/patchers/dynamicHeadAppend.ts b/src/sandbox/patchers/dynamicHeadAppend.ts index e0c1ebcf7..1aab64f73 100644 --- a/src/sandbox/patchers/dynamicHeadAppend.ts +++ b/src/sandbox/patchers/dynamicHeadAppend.ts @@ -194,7 +194,7 @@ function getNewInsertBefore(...args: any[]) { // have storedContainerInfo means it invoked by a micro app const invokedByMicroApp = storedContainerInfo && !singular; const wrapper = appWrapperGetter(); - let referenceNode = wrapper.contains(refChild) ? refChild : null; + const referenceNode = wrapper.contains(refChild) ? refChild : null; switch (element.tagName) { case LINK_TAG_NAME: @@ -220,9 +220,7 @@ function getNewInsertBefore(...args: any[]) { } case SCRIPT_TAG_NAME: { if (!invokedByMicroApp) { - referenceNode = this.contains(refChild) ? refChild : null; - - return rawHeadInsertBefore.call(this, element, referenceNode) as T; + return rawHeadInsertBefore.call(this, element, refChild) as T; } const { src, text } = element as HTMLScriptElement;