Skip to content

Commit d08037c

Browse files
authored
fix: retain currentScript reference when processing async/defer scripts to prevent data-* attribute read failures
1 parent 7d5b153 commit d08037c

File tree

3 files changed

+66
-27
lines changed

3 files changed

+66
-27
lines changed

dev/app-react-18/public/index.html

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,12 @@
22
<html>
33
<head>
44
<meta charset="UTF-8">
5-
<title>app react v17</title>
5+
<title>app react v18</title>
6+
<script
7+
src="./scripts/readCurrentScript.js"
8+
data-appkey="supply"
9+
async="true"
10+
></script>
611
</head>
712
<body>
813
<div id="root"></div>
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
const currentScript = document.currentScript;
2+
if (!currentScript.dataset.testName) {
3+
throw new Error('currentScript.dataset.testName is required')
4+
}
5+

packages/core/src/module/app.ts

Lines changed: 55 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ export class App {
9898
// Environment variables injected by garfish for linkage with child applications
9999
private globalEnvVariables: Record<string, any>;
100100
private deferNodeMap = new Map();
101+
private asyncNodeMap = new Map();
101102
private resolveAsyncProvider: () => void | undefined;
102103
private asyncProvider?:
103104
| interfaces.Provider
@@ -476,18 +477,42 @@ export class App {
476477
let noEntry = false;
477478
const targetUrl = jsManager.url || this.appInfo.entry;
478479

480+
const mockOriginScript = document.createElement('script');
481+
479482
if (type === 'defer') {
480483
const node = this.deferNodeMap.get(jsManager);
481484
if (node) {
482485
noEntry = toBoolean(
483486
this.entryManager.findAttributeValue(node, 'no-entry'),
484487
);
488+
489+
node.attributes.forEach((attribute) => {
490+
if (attribute.key) {
491+
mockOriginScript.setAttribute(
492+
attribute.key,
493+
attribute.value || '',
494+
);
495+
}
496+
});
485497
}
486498
// Try to read the childApp global configuration
487499
if (!noEntry) {
488500
noEntry = toBoolean(this.isNoEntryScript(targetUrl));
489501
}
490502
}
503+
504+
const node = this.asyncNodeMap.get(jsManager);
505+
if (node) {
506+
node.attributes.forEach((attribute) => {
507+
if (attribute.key) {
508+
mockOriginScript.setAttribute(
509+
attribute.key,
510+
attribute.value || '',
511+
);
512+
}
513+
});
514+
}
515+
491516
this.execScript(jsManager.scriptCode, {}, targetUrl, {
492517
noEntry,
493518
defer: type === 'defer',
@@ -703,36 +728,40 @@ export class App {
703728
}
704729

705730
const jsManager = resources.js.find((manager) => {
706-
return !manager.async ? manager.isSameOrigin(node) : false;
731+
if (manager.async) {
732+
this.asyncNodeMap.set(manager, node);
733+
return false;
734+
}
735+
if (manager.defer) {
736+
this.deferNodeMap.set(manager, node);
737+
return false;
738+
}
739+
return manager.isSameOrigin(node);
707740
});
708741

709742
if (jsManager) {
710-
if (jsManager.defer) {
711-
this.deferNodeMap.set(jsManager, node);
712-
} else {
713-
const { url, scriptCode } = jsManager;
714-
const mockOriginScript = document.createElement('script');
715-
node.attributes.forEach((attribute) => {
716-
if (attribute.key) {
717-
mockOriginScript.setAttribute(
718-
attribute.key,
719-
attribute.value || '',
720-
);
721-
}
722-
});
743+
const { url, scriptCode } = jsManager;
744+
const mockOriginScript = document.createElement('script');
745+
node.attributes.forEach((attribute) => {
746+
if (attribute.key) {
747+
mockOriginScript.setAttribute(
748+
attribute.key,
749+
attribute.value || '',
750+
);
751+
}
752+
});
723753

724-
const targetUrl = url || this.appInfo.entry;
725-
this.execScript(scriptCode, {}, targetUrl, {
726-
isModule,
727-
async: false,
728-
defer: false,
729-
isInline: jsManager.isInlineScript(),
730-
noEntry:
731-
toBoolean(entryManager.findAttributeValue(node, 'no-entry')) ||
732-
toBoolean(this.isNoEntryScript(targetUrl)),
733-
originScript: mockOriginScript,
734-
});
735-
}
754+
const targetUrl = url || this.appInfo.entry;
755+
this.execScript(scriptCode, {}, targetUrl, {
756+
isModule,
757+
async: false,
758+
defer: false,
759+
isInline: jsManager.isInlineScript(),
760+
noEntry:
761+
toBoolean(entryManager.findAttributeValue(node, 'no-entry')) ||
762+
toBoolean(this.isNoEntryScript(targetUrl)),
763+
originScript: mockOriginScript,
764+
});
736765
} else if (__DEV__) {
737766
const async = entryManager.findAttributeValue(node, 'async');
738767
if (typeof async === 'undefined' || async === 'false') {

0 commit comments

Comments
 (0)