diff --git a/packages/angular/build/src/builders/application/tests/behavior/component-stylesheets_spec.ts b/packages/angular/build/src/builders/application/tests/behavior/component-stylesheets_spec.ts index ddae750a64a4..0fb1fb22c9fa 100644 --- a/packages/angular/build/src/builders/application/tests/behavior/component-stylesheets_spec.ts +++ b/packages/angular/build/src/builders/application/tests/behavior/component-stylesheets_spec.ts @@ -64,6 +64,25 @@ describeBuilder(buildApplication, APPLICATION_BUILDER_INFO, (harness) => { ); }); + it('should generate an error when a styleUrl points to a TypeScript file', async () => { + await harness.modifyFile('src/app/app.component.ts', (content) => { + return content.replace('./app.component.css', './app.component.ts'); + }); + + harness.useTarget('build', { + ...BASE_OPTIONS, + }); + + const { result, logs } = await harness.executeOnce({ outputLogsOnFailure: false }); + expect(result?.success).toBeFalse(); + expect(logs).toContain( + jasmine.objectContaining({ + level: 'error', + message: jasmine.stringContaining(`Could not find stylesheet file './app.component.ts'`), + }), + ); + }); + it('should generate an error for a missing stylesheet with JIT', async () => { await harness.modifyFile('src/app/app.component.ts', (content) => { return content.replace('./app.component.css', './not-present.css'); diff --git a/packages/angular/build/src/tools/angular/angular-host.ts b/packages/angular/build/src/tools/angular/angular-host.ts index e98ebf49f3eb..d4cae1bab980 100644 --- a/packages/angular/build/src/tools/angular/angular-host.ts +++ b/packages/angular/build/src/tools/angular/angular-host.ts @@ -212,6 +212,12 @@ export function createAngularCompilerHost( return null; } + // Reject TypeScript files used as component resources (e.g., styleUrl pointing to a .ts file). + // Processing a TypeScript file as a stylesheet or template causes confusing downstream errors. + if (hasTypeScriptExtension(resolvedPath)) { + return null; + } + // All resource names that have template file extensions are assumed to be templates // TODO: Update compiler to provide the resource type to avoid extension matching here. if (!hostOptions.externalStylesheets || hasTemplateExtension(resolvedPath)) { @@ -256,14 +262,9 @@ export function createAngularCompilerHost( } function hasTemplateExtension(file: string): boolean { - const extension = nodePath.extname(file).toLowerCase(); - - switch (extension) { - case '.htm': - case '.html': - case '.svg': - return true; - } + return ['.htm', '.html', '.svg'].includes(nodePath.extname(file).toLowerCase()); +} - return false; +function hasTypeScriptExtension(file: string): boolean { + return ['.ts', '.tsx', '.mts', '.cts'].includes(nodePath.extname(file).toLowerCase()); }