Skip to content

Commit 0bfcaef

Browse files
committed
feat(@angular-devkit/build-angular): add defer attributes to classic scripts
This change synchronizes the behavior of classic scripts and module scripts (`type="module"`). Module scripts are deferred by default. Also, certain injected scripts are not considered module scripts even in a ES2015+ build due to the strict mode behavior of module scripts. Deferring such scripts also ensures consistent execution in those scenarios.
1 parent b5924fe commit 0bfcaef

File tree

15 files changed

+130
-126
lines changed

15 files changed

+130
-126
lines changed

packages/angular_devkit/build_angular/src/angular-cli-files/utilities/index-file/augment-index-html.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -150,10 +150,14 @@ export async function augmentIndexHtml(params: AugmentIndexHtmlOptions): Promise
150150
const isModuleType = moduleFiles.some(scriptPredictor);
151151

152152
if (isNoModuleType && !isModuleType) {
153-
attrs.push({ name: 'nomodule', value: null });
153+
attrs.push({ name: 'nomodule', value: null }, { name: 'defer', value: null });
154154
} else if (isModuleType && !isNoModuleType) {
155155
attrs.push({ name: 'type', value: 'module' });
156+
} else {
157+
attrs.push({ name: 'defer', value: null });
156158
}
159+
} else {
160+
attrs.push({ name: 'defer', value: null });
157161
}
158162

159163
if (params.sri) {

packages/angular_devkit/build_angular/src/angular-cli-files/utilities/index-file/augment-index-html_spec.ts

+8-8
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,9 @@ describe('augment-index-html', () => {
4141
<link rel="stylesheet" href="styles.css">
4242
</head>
4343
<body>
44-
<script src="runtime.js"></script>
45-
<script src="polyfills.js"></script>
46-
<script src="main.js"></script>
44+
<script src="runtime.js" defer></script>
45+
<script src="polyfills.js" defer></script>
46+
<script src="main.js" defer></script>
4747
</body>
4848
</html>
4949
`);
@@ -84,10 +84,10 @@ describe('augment-index-html', () => {
8484
<body>
8585
<script src="runtime-es2015.js" type="module"></script>
8686
<script src="polyfills-es2015.js" type="module"></script>
87-
<script src="runtime-es5.js" nomodule></script>
88-
<script src="polyfills-es5.js" nomodule></script>
87+
<script src="runtime-es5.js" nomodule defer></script>
88+
<script src="polyfills-es5.js" nomodule defer></script>
8989
<script src="main-es2015.js" type="module"></script>
90-
<script src="main-es5.js" nomodule></script>
90+
<script src="main-es5.js" nomodule defer></script>
9191
</body>
9292
</html>
9393
`);
@@ -124,9 +124,9 @@ describe('augment-index-html', () => {
124124
<link rel="stylesheet" href="styles.css">
125125
</head>
126126
<body>
127-
<script src="scripts.js"></script>
127+
<script src="scripts.js" defer></script>
128128
<script src="main-es2015.js" type="module"></script>
129-
<script src="main-es5.js" nomodule></script>
129+
<script src="main-es5.js" nomodule defer></script>
130130
</body>
131131
</html>
132132
`);

packages/angular_devkit/build_angular/test/browser/cross-origin_spec_large.ts

+15-15
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,11 @@ describe('Browser Builder crossOrigin', () => {
4040
expect(content).toBe(
4141
`<html><head><base href="/"></head>` +
4242
`<body><app-root></app-root>` +
43-
`<script src="runtime.js" crossorigin="use-credentials"></script>` +
44-
`<script src="polyfills.js" crossorigin="use-credentials"></script>` +
45-
`<script src="styles.js" crossorigin="use-credentials"></script>` +
46-
`<script src="vendor.js" crossorigin="use-credentials"></script>` +
47-
`<script src="main.js" crossorigin="use-credentials"></script></body></html>`,
43+
`<script src="runtime.js" crossorigin="use-credentials" defer></script>` +
44+
`<script src="polyfills.js" crossorigin="use-credentials" defer></script>` +
45+
`<script src="styles.js" crossorigin="use-credentials" defer></script>` +
46+
`<script src="vendor.js" crossorigin="use-credentials" defer></script>` +
47+
`<script src="main.js" crossorigin="use-credentials" defer></script></body></html>`,
4848
);
4949
await run.stop();
5050
});
@@ -59,11 +59,11 @@ describe('Browser Builder crossOrigin', () => {
5959
expect(content).toBe(
6060
`<html><head><base href="/"></head>` +
6161
`<body><app-root></app-root>` +
62-
`<script src="runtime.js" crossorigin="anonymous"></script>` +
63-
`<script src="polyfills.js" crossorigin="anonymous"></script>` +
64-
`<script src="styles.js" crossorigin="anonymous"></script>` +
65-
`<script src="vendor.js" crossorigin="anonymous"></script>` +
66-
`<script src="main.js" crossorigin="anonymous"></script></body></html>`,
62+
`<script src="runtime.js" crossorigin="anonymous" defer></script>` +
63+
`<script src="polyfills.js" crossorigin="anonymous" defer></script>` +
64+
`<script src="styles.js" crossorigin="anonymous" defer></script>` +
65+
`<script src="vendor.js" crossorigin="anonymous" defer></script>` +
66+
`<script src="main.js" crossorigin="anonymous" defer></script></body></html>`,
6767
);
6868
await run.stop();
6969
});
@@ -78,11 +78,11 @@ describe('Browser Builder crossOrigin', () => {
7878
expect(content).toBe(
7979
`<html><head><base href="/"></head>` +
8080
`<body><app-root></app-root>` +
81-
`<script src="runtime.js"></script>` +
82-
`<script src="polyfills.js"></script>` +
83-
`<script src="styles.js"></script>` +
84-
`<script src="vendor.js"></script>` +
85-
`<script src="main.js"></script></body></html>`,
81+
`<script src="runtime.js" defer></script>` +
82+
`<script src="polyfills.js" defer></script>` +
83+
`<script src="styles.js" defer></script>` +
84+
`<script src="vendor.js" defer></script>` +
85+
`<script src="main.js" defer></script></body></html>`,
8686
);
8787
await run.stop();
8888
});

packages/angular_devkit/build_angular/test/browser/index_spec_large.ts

+21-21
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,9 @@ describe('Browser Builder index HTML processing', () => {
3535
const content = virtualFs.fileBufferToString(await host.read(normalize(fileName)).toPromise());
3636
expect(content).toBe(
3737
`<html><head><base href="/"></head>`
38-
+ `<body><app-root></app-root><script src="runtime.js"></script>`
39-
+ `<script src="polyfills.js"></script><script src="styles.js"></script>`
40-
+ `<script src="vendor.js"></script><script src="main.js"></script></body></html>`,
38+
+ `<body><app-root></app-root><script src="runtime.js" defer></script>`
39+
+ `<script src="polyfills.js" defer></script><script src="styles.js" defer></script>`
40+
+ `<script src="vendor.js" defer></script><script src="main.js" defer></script></body></html>`,
4141
);
4242
await run.stop();
4343
});
@@ -57,9 +57,9 @@ describe('Browser Builder index HTML processing', () => {
5757
const content = virtualFs.fileBufferToString(await host.read(normalize(fileName)).toPromise());
5858
expect(content).toBe(
5959
`<html><head><base href="/"></head><body><app-root></app-root>`
60-
+ `<script src="runtime.js"></script><script src="polyfills.js"></script>`
61-
+ `<script src="styles.js"></script><script src="vendor.js"></script>`
62-
+ `<script src="main.js"></script></body></html>`,
60+
+ `<script src="runtime.js" defer></script><script src="polyfills.js" defer></script>`
61+
+ `<script src="styles.js" defer></script><script src="vendor.js" defer></script>`
62+
+ `<script src="main.js" defer></script></body></html>`,
6363
);
6464
await run.stop();
6565
});
@@ -79,9 +79,9 @@ describe('Browser Builder index HTML processing', () => {
7979
const content = virtualFs.fileBufferToString(await host.read(normalize(fileName)).toPromise());
8080
expect(content).toBe(
8181
`<html><head><title>&iacute;</title><base href="/"></head> `
82-
+ `<body><app-root></app-root><script src="runtime.js"></script>`
83-
+ `<script src="polyfills.js"></script><script src="styles.js"></script>`
84-
+ `<script src="vendor.js"></script><script src="main.js"></script></body></html>`,
82+
+ `<body><app-root></app-root><script src="runtime.js" defer></script>`
83+
+ `<script src="polyfills.js" defer></script><script src="styles.js" defer></script>`
84+
+ `<script src="vendor.js" defer></script><script src="main.js" defer></script></body></html>`,
8585
);
8686
await run.stop();
8787
});
@@ -101,9 +101,9 @@ describe('Browser Builder index HTML processing', () => {
101101
const content = virtualFs.fileBufferToString(await host.read(normalize(fileName)).toPromise());
102102
expect(content).toBe(
103103
`<html><head><base href="/"><%= csrf_meta_tags %></head> `
104-
+ `<body><app-root></app-root><script src="runtime.js"></script>`
105-
+ `<script src="polyfills.js"></script><script src="styles.js"></script>`
106-
+ `<script src="vendor.js"></script><script src="main.js"></script></body></html>`,
104+
+ `<body><app-root></app-root><script src="runtime.js" defer></script>`
105+
+ `<script src="polyfills.js" defer></script><script src="styles.js" defer></script>`
106+
+ `<script src="vendor.js" defer></script><script src="main.js" defer></script></body></html>`,
107107
);
108108
await run.stop();
109109
});
@@ -146,9 +146,9 @@ describe('Browser Builder index HTML processing', () => {
146146
const content = await host.read(normalize(outputIndexPath)).toPromise();
147147
expect(virtualFs.fileBufferToString(content)).toBe(
148148
`<html><head><base href="/"><%= csrf_meta_tags %></head> `
149-
+ `<body><app-root></app-root><script src="runtime.js"></script>`
150-
+ `<script src="polyfills.js"></script><script src="styles.js"></script>`
151-
+ `<script src="vendor.js"></script><script src="main.js"></script></body></html>`,
149+
+ `<body><app-root></app-root><script src="runtime.js" defer></script>`
150+
+ `<script src="polyfills.js" defer></script><script src="styles.js" defer></script>`
151+
+ `<script src="vendor.js" defer></script><script src="main.js" defer></script></body></html>`,
152152
);
153153
});
154154

@@ -189,9 +189,9 @@ describe('Browser Builder index HTML processing', () => {
189189
const content = await host.read(normalize(outputIndexPath)).toPromise();
190190
expect(virtualFs.fileBufferToString(content)).toBe(
191191
`<html><head><base href="/"></head> `
192-
+ `<body><app-root></app-root><script src="runtime.js"></script>`
193-
+ `<script src="polyfills.js"></script><script src="styles.js"></script>`
194-
+ `<script src="vendor.js"></script><script src="main.js"></script></body></html>`,
192+
+ `<body><app-root></app-root><script src="runtime.js" defer></script>`
193+
+ `<script src="polyfills.js" defer></script><script src="styles.js" defer></script>`
194+
+ `<script src="vendor.js" defer></script><script src="main.js" defer></script></body></html>`,
195195
);
196196
});
197197

@@ -232,9 +232,9 @@ describe('Browser Builder index HTML processing', () => {
232232
const content = await host.read(normalize(outputIndexPath)).toPromise();
233233
expect(virtualFs.fileBufferToString(content)).toBe(
234234
`<html><head><base href="/"></head> `
235-
+ `<body><app-root></app-root><script src="runtime.js"></script>`
236-
+ `<script src="polyfills.js"></script><script src="styles.js"></script>`
237-
+ `<script src="vendor.js"></script><script src="main.js"></script></body></html>`,
235+
+ `<body><app-root></app-root><script src="runtime.js" defer></script>`
236+
+ `<script src="polyfills.js" defer></script><script src="styles.js" defer></script>`
237+
+ `<script src="vendor.js" defer></script><script src="main.js" defer></script></body></html>`,
238238
);
239239
});
240240
});

packages/angular_devkit/build_angular/test/browser/scripts-array_spec_large.ts

+6-6
Original file line numberDiff line numberDiff line change
@@ -54,12 +54,12 @@ describe('Browser Builder scripts array', () => {
5454
'renamed-script.js': 'pre-rename-script',
5555
'renamed-lazy-script.js': 'pre-rename-lazy-script',
5656
'main.js': 'input-script',
57-
'index.html': '<script src="runtime.js"></script>'
58-
+ '<script src="polyfills.js"></script>'
59-
+ '<script src="scripts.js"></script>'
60-
+ '<script src="renamed-script.js"></script>'
61-
+ '<script src="vendor.js"></script>'
62-
+ '<script src="main.js"></script>',
57+
'index.html': '<script src="runtime.js" defer></script>'
58+
+ '<script src="polyfills.js" defer></script>'
59+
+ '<script src="scripts.js" defer></script>'
60+
+ '<script src="renamed-script.js" defer></script>'
61+
+ '<script src="vendor.js" defer></script>'
62+
+ '<script src="main.js" defer></script>',
6363
};
6464

6565
host.writeMultipleFiles(scripts);

packages/angular_devkit/build_angular/test/browser/service-worker_spec_large.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ describe('Browser Builder service worker', () => {
110110
hashTable: {
111111
'/favicon.ico': '84161b857f5c547e3699ddfbffc6d8d737542e01',
112112
'/assets/folder-asset.txt': '617f202968a6a81050aa617c2e28e1dca11ce8d4',
113-
'/index.html': '1bcafd53046ffb270ac5e6f3cab23e0442f95c4f',
113+
'/index.html': 'f95e7a84949070c4984069b592be7969bc3187a0',
114114
'/spectrum.png': '8d048ece46c0f3af4b598a95fd8e4709b631c3c0',
115115
},
116116
}));
@@ -167,7 +167,7 @@ describe('Browser Builder service worker', () => {
167167
hashTable: {
168168
'/foo/bar/favicon.ico': '84161b857f5c547e3699ddfbffc6d8d737542e01',
169169
'/foo/bar/assets/folder-asset.txt': '617f202968a6a81050aa617c2e28e1dca11ce8d4',
170-
'/foo/bar/index.html': '925d80777b6ba64b526b0be79761d254dfe94c65',
170+
'/foo/bar/index.html': 'a5359e8e1a516683b32bbb2f9e8bf402dae4738e',
171171
},
172172
}));
173173

packages/angular_devkit/build_angular/test/browser/styles_spec_large.ts

+6-6
Original file line numberDiff line numberDiff line change
@@ -54,12 +54,12 @@ describe('Browser Builder styles', () => {
5454
};
5555
const jsIndexMatches: { [path: string]: string } = {
5656
'index.html':
57-
'<script src="runtime.js"></script>' +
58-
'<script src="polyfills.js"></script>' +
59-
'<script src="styles.js"></script>' +
60-
'<script src="renamed-style.js"></script>' +
61-
'<script src="vendor.js"></script>' +
62-
'<script src="main.js"></script>',
57+
'<script src="runtime.js" defer></script>' +
58+
'<script src="polyfills.js" defer></script>' +
59+
'<script src="styles.js" defer></script>' +
60+
'<script src="renamed-style.js" defer></script>' +
61+
'<script src="vendor.js" defer></script>' +
62+
'<script src="main.js" defer></script>',
6363
};
6464

6565
host.writeMultipleFiles({

packages/angular_devkit/build_angular/test/dev-server/index_spec_large.ts

+6-6
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ describe('Dev Server Builder index', () => {
7676
'<script src="runtime.js" type="module"></script>' +
7777
'<script src="polyfills.js" type="module"></script>' +
7878
'<script src="styles.js" type="module"></script>' +
79-
'<script src="scripts.js"></script>' +
79+
'<script src="scripts.js" defer></script>' +
8080
'<script src="vendor.js" type="module"></script>' +
8181
'<script src="main.js" type="module"></script>',
8282
);
@@ -96,11 +96,11 @@ describe('Dev Server Builder index', () => {
9696
expect(output.success).toBe(true);
9797
const response = await fetch('http://localhost:4200/index.html');
9898
expect(await response.text()).toContain(
99-
'<script src="runtime.js"></script>' +
100-
'<script src="polyfills.js"></script>' +
101-
'<script src="styles.js"></script>' +
102-
'<script src="vendor.js"></script>' +
103-
'<script src="main.js"></script>',
99+
'<script src="runtime.js" defer></script>' +
100+
'<script src="polyfills.js" defer></script>' +
101+
'<script src="styles.js" defer></script>' +
102+
'<script src="vendor.js" defer></script>' +
103+
'<script src="main.js" defer></script>',
104104
);
105105
await run.stop();
106106
});

tests/legacy-cli/e2e/tests/basic/scripts-array.ts

+6-6
Original file line numberDiff line numberDiff line change
@@ -67,14 +67,14 @@ export default function() {
6767
oneLineTrim`
6868
<script src="runtime-es2015.js" type="module"></script>
6969
<script src="polyfills-es2015.js" type="module"></script>
70-
<script src="runtime-es5.js" nomodule></script>
71-
<script src="polyfills-es5.js" nomodule></script>
72-
<script src="scripts.js"></script>
73-
<script src="renamed-script.js"></script>
70+
<script src="runtime-es5.js" nomodule defer></script>
71+
<script src="polyfills-es5.js" nomodule defer></script>
72+
<script src="scripts.js" defer></script>
73+
<script src="renamed-script.js" defer></script>
7474
<script src="vendor-es2015.js" type="module"></script>
7575
<script src="main-es2015.js" type="module"></script>
76-
<script src="vendor-es5.js" nomodule></script>
77-
<script src="main-es5.js" nomodule></script>
76+
<script src="vendor-es5.js" nomodule defer></script>
77+
<script src="main-es5.js" nomodule defer></script>
7878
`,
7979
),
8080
)

tests/legacy-cli/e2e/tests/basic/styles-array.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -55,12 +55,12 @@ export default function() {
5555
oneLineTrim`
5656
<script src="runtime-es2015.js" type="module"></script>
5757
<script src="polyfills-es2015.js" type="module"></script>
58-
<script src="runtime-es5.js" nomodule></script>
59-
<script src="polyfills-es5.js" nomodule></script>
58+
<script src="runtime-es5.js" nomodule defer></script>
59+
<script src="polyfills-es5.js" nomodule defer></script>
6060
<script src="vendor-es2015.js" type="module"></script>
6161
<script src="main-es2015.js" type="module"></script>
62-
<script src="vendor-es5.js" nomodule></script>
63-
<script src="main-es5.js" nomodule></script>
62+
<script src="vendor-es5.js" nomodule defer></script>
63+
<script src="main-es5.js" nomodule defer></script>
6464
`,
6565
),
6666
)

tests/legacy-cli/e2e/tests/build/polyfills.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ export default async function () {
1616
await expectFileToMatch('dist/test-project/index.html', oneLineTrim`
1717
<script src="runtime-es2015.js" type="module"></script>
1818
<script src="polyfills-es2015.js" type="module"></script>
19-
<script src="runtime-es5.js" nomodule></script>
20-
<script src="polyfills-es5.js" nomodule></script>
19+
<script src="runtime-es5.js" nomodule defer></script>
20+
<script src="polyfills-es5.js" nomodule defer></script>
2121
`);
2222
const jitPolyfillSize = await getFileSize('dist/test-project/polyfills-es5.js');
2323

@@ -30,7 +30,7 @@ export default async function () {
3030
await expectFileToMatch('dist/test-project/index.html', oneLineTrim`
3131
<script src="runtime-es2015.js" type="module"></script>
3232
<script src="polyfills-es2015.js" type="module"></script>
33-
<script src="runtime-es5.js" nomodule></script>
34-
<script src="polyfills-es5.js" nomodule></script>
33+
<script src="runtime-es5.js" nomodule defer></script>
34+
<script src="polyfills-es5.js" nomodule defer></script>
3535
`);
3636
}

tests/legacy-cli/e2e/tests/build/styles/extract-css.ts

+10-10
Original file line numberDiff line numberDiff line change
@@ -74,12 +74,12 @@ export default function() {
7474
oneLineTrim`
7575
<script src="runtime-es2015.js" type="module"></script>
7676
<script src="polyfills-es2015.js" type="module"></script>
77-
<script src="runtime-es5.js" nomodule></script>
78-
<script src="polyfills-es5.js" nomodule></script>
77+
<script src="runtime-es5.js" nomodule defer></script>
78+
<script src="polyfills-es5.js" nomodule defer></script>
7979
<script src="vendor-es2015.js" type="module"></script>
8080
<script src="main-es2015.js" type="module"></script>
81-
<script src="vendor-es5.js" nomodule></script>
82-
<script src="main-es5.js" nomodule></script>
81+
<script src="vendor-es5.js" nomodule defer></script>
82+
<script src="main-es5.js" nomodule defer></script>
8383
`,
8484
),
8585
)
@@ -112,16 +112,16 @@ export default function() {
112112
oneLineTrim`
113113
<script src="runtime-es2015.js" type="module"></script>
114114
<script src="polyfills-es2015.js" type="module"></script>
115-
<script src="runtime-es5.js" nomodule></script>
116-
<script src="polyfills-es5.js" nomodule></script>
115+
<script src="runtime-es5.js" nomodule defer></script>
116+
<script src="polyfills-es5.js" nomodule defer></script>
117117
<script src="styles-es2015.js" type="module"></script>
118-
<script src="styles-es5.js" nomodule></script>
118+
<script src="styles-es5.js" nomodule defer></script>
119119
<script src="renamed-style-es2015.js" type="module"></script>
120-
<script src="renamed-style-es5.js" nomodule></script>
120+
<script src="renamed-style-es5.js" nomodule defer></script>
121121
<script src="vendor-es2015.js" type="module"></script>
122122
<script src="main-es2015.js" type="module"></script>
123-
<script src="vendor-es5.js" nomodule></script>
124-
<script src="main-es5.js" nomodule></script>
123+
<script src="vendor-es5.js" nomodule defer></script>
124+
<script src="main-es5.js" nomodule defer></script>
125125
`,
126126
),
127127
)

0 commit comments

Comments
 (0)