diff --git a/packages/angular_devkit/build_angular/src/builders/application/tests/behavior/index-preload-hints_spec.ts b/packages/angular_devkit/build_angular/src/builders/application/tests/behavior/index-preload-hints_spec.ts index 342f7a94e4b6..25bafd22881f 100644 --- a/packages/angular_devkit/build_angular/src/builders/application/tests/behavior/index-preload-hints_spec.ts +++ b/packages/angular_devkit/build_angular/src/builders/application/tests/behavior/index-preload-hints_spec.ts @@ -30,7 +30,7 @@ describeBuilder(buildApplication, APPLICATION_BUILDER_INFO, (harness) => { harness .expectFile('dist/index.html') .content.toContain( - '', + '', ); }); }); diff --git a/packages/angular_devkit/build_angular/src/tools/esbuild/index-html-generator.ts b/packages/angular_devkit/build_angular/src/tools/esbuild/index-html-generator.ts index 3a113c6d9693..4cad522b42ae 100644 --- a/packages/angular_devkit/build_angular/src/tools/esbuild/index-html-generator.ts +++ b/packages/angular_devkit/build_angular/src/tools/esbuild/index-html-generator.ts @@ -45,7 +45,9 @@ export function generateIndexHtml( if (value.type === 'script') { hints.push({ url: key, mode: 'modulepreload' as const }); } else if (value.type === 'style') { - hints.push({ url: key, mode: 'preload' as const }); + // Provide an "as" value of "style" to ensure external URLs which may not have a + // file extension are treated as stylesheets. + hints.push({ url: key, mode: 'preload' as const, as: 'style' }); } } } diff --git a/packages/angular_devkit/build_angular/src/utils/index-file/augment-index-html.ts b/packages/angular_devkit/build_angular/src/utils/index-file/augment-index-html.ts index 44173a65a182..a16fc8aa80b7 100644 --- a/packages/angular_devkit/build_angular/src/utils/index-file/augment-index-html.ts +++ b/packages/angular_devkit/build_angular/src/utils/index-file/augment-index-html.ts @@ -39,7 +39,7 @@ export interface AugmentIndexHtmlOptions { entrypoints: Entrypoint[]; /** Used to set the document default locale */ lang?: string; - hints?: { url: string; mode: string }[]; + hints?: { url: string; mode: string; as?: string }[]; } export interface FileInfo { @@ -152,6 +152,11 @@ export async function augmentIndexHtml( case '.css': attrs.push('as="style"'); break; + default: + if (hint.as) { + attrs.push(`as="${hint.as}"`); + } + break; } } diff --git a/packages/angular_devkit/build_angular/src/utils/index-file/augment-index-html_spec.ts b/packages/angular_devkit/build_angular/src/utils/index-file/augment-index-html_spec.ts index ab39512e2435..6a51acee5012 100644 --- a/packages/angular_devkit/build_angular/src/utils/index-file/augment-index-html_spec.ts +++ b/packages/angular_devkit/build_angular/src/utils/index-file/augment-index-html_spec.ts @@ -375,6 +375,29 @@ describe('augment-index-html', () => { `); }); + it(`should add prefetch/preload hints with as=style when specified with a URL and an 'as' option`, async () => { + const { content, warnings } = await augmentIndexHtml({ + ...indexGeneratorOptions, + hints: [ + { mode: 'prefetch', url: 'https://example.com/x?a=1', as: 'style' }, + { mode: 'preload', url: 'http://example.com/y?b=2', as: 'style' }, + ], + }); + + expect(warnings).toHaveSize(0); + expect(content).toEqual(oneLineHtml` + +
+