diff --git a/packages/angular/build/src/tools/angular/compilation/angular-compilation_spec.ts b/packages/angular/build/src/tools/angular/compilation/angular-compilation_spec.ts index a867f666c349..71eacd562259 100644 --- a/packages/angular/build/src/tools/angular/compilation/angular-compilation_spec.ts +++ b/packages/angular/build/src/tools/angular/compilation/angular-compilation_spec.ts @@ -8,7 +8,7 @@ import ts from 'typescript'; import type { AngularHostOptions } from '../angular-host'; -import { transformCompilerOptions } from './compiler-options'; +import { CompilerOptionOverrides, transformCompilerOptions } from './compiler-options'; import { TypeScriptCompilation } from './typescript-compilation'; import { AngularCompilation, @@ -90,6 +90,10 @@ describe('AngularCompilation', () => { public getCachedSourceFiles(): Map { return this.sourceFiles; } + + public async testLoadConfiguration(tsconfig: string, overrides?: CompilerOptionOverrides) { + return this.loadConfiguration(tsconfig, overrides); + } } it('collects and converts diagnostics categorized by error and warning', async () => { @@ -134,6 +138,32 @@ describe('AngularCompilation', () => { expect(compilerCli).toBeDefined(); expect(typeof compilerCli.readConfiguration).toBe('function'); }); + + it('loads configuration and applies compiler option transformations', async () => { + const compilation = new MockTypeScriptCompilation(); + const mockReadConfig = jasmine.createSpy('readConfiguration').and.returnValue({ + options: { target: ts.ScriptTarget.ES2020 }, + rootNames: ['/src/main.ts'], + errors: [], + }); + spyOn(TypeScriptCompilation, 'loadCompilerCli').and.resolveTo({ + readConfiguration: mockReadConfig, + } as unknown as typeof import('@angular/compiler-cli')); + + const result = await compilation.testLoadConfiguration('tsconfig.json', { sourcemap: true }); + + expect(mockReadConfig).toHaveBeenCalledWith( + 'tsconfig.json', + jasmine.objectContaining({ + suppressOutputPathCheck: true, + outDir: undefined, + }), + ); + expect(result.rootNames).toEqual(['/src/main.ts']); + expect(result.compilerOptions.target).toBe(ts.ScriptTarget.ES2022); + expect(result.compilerOptions.inlineSources).toBe(true); + expect(result.warnings.length).toBeGreaterThan(0); + }); }); describe('createAngularCompilation', () => { diff --git a/packages/angular/build/src/tools/angular/compilation/aot-compilation.ts b/packages/angular/build/src/tools/angular/compilation/aot-compilation.ts index 9fd160774cf7..ca74e721ba7d 100644 --- a/packages/angular/build/src/tools/angular/compilation/aot-compilation.ts +++ b/packages/angular/build/src/tools/angular/compilation/aot-compilation.ts @@ -7,7 +7,6 @@ */ import type * as ng from '@angular/compiler-cli'; -import type { PartialMessage } from 'esbuild'; import assert from 'node:assert'; import { relative } from 'node:path'; import ts from 'typescript'; @@ -26,7 +25,7 @@ import { DiagnosticModes, type EmitFileResult, } from './angular-compilation'; -import { CompilerOptionOverrides, transformCompilerOptions } from './compiler-options'; +import type { CompilerOptionOverrides } from './compiler-options'; import { collectHmrCandidates } from './hmr-candidates'; import { TypeScriptCompilation } from './typescript-compilation'; import { printSourceFileWithMap } from './typescript-printer'; @@ -72,17 +71,11 @@ export class AotCompilation extends TypeScriptCompilation { // Load the compiler configuration and transform as needed const { - options: originalCompilerOptions, + compilerOptions, rootNames, errors: configurationDiagnostics, - } = await this.loadConfiguration(tsconfig); - - const { compilerOptions, warnings } = transformCompilerOptions( - ts, - originalCompilerOptions, - compilerOptionOverrides, - tsconfig, - ); + warnings, + } = await this.loadConfiguration(tsconfig, compilerOptionOverrides); const useTypeScriptTranspilation = (compilerOptions['_useTypeScriptTranspilation'] as boolean | undefined) ?? diff --git a/packages/angular/build/src/tools/angular/compilation/jit-compilation.ts b/packages/angular/build/src/tools/angular/compilation/jit-compilation.ts index fee636219be0..233f5977e5a6 100644 --- a/packages/angular/build/src/tools/angular/compilation/jit-compilation.ts +++ b/packages/angular/build/src/tools/angular/compilation/jit-compilation.ts @@ -7,7 +7,6 @@ */ import type * as ng from '@angular/compiler-cli'; -import type { PartialMessage } from 'esbuild'; import assert from 'node:assert'; import ts from 'typescript'; import { profileSync } from '../../esbuild/profiling'; @@ -20,7 +19,7 @@ import { DiagnosticModes, type EmitFileResult, } from './angular-compilation'; -import { CompilerOptionOverrides, transformCompilerOptions } from './compiler-options'; +import type { CompilerOptionOverrides } from './compiler-options'; import { TypeScriptCompilation } from './typescript-compilation'; class JitCompilationState { @@ -51,17 +50,11 @@ export class JitCompilation extends TypeScriptCompilation { // Load the compiler configuration and transform as needed const { - options: originalCompilerOptions, + compilerOptions, rootNames, errors: configurationDiagnostics, - } = await this.loadConfiguration(tsconfig); - - const { compilerOptions, warnings } = transformCompilerOptions( - ts, - originalCompilerOptions, - compilerOptionOverrides, - tsconfig, - ); + warnings, + } = await this.loadConfiguration(tsconfig, compilerOptionOverrides); if (hostOptions.modifiedFiles) { this.invalidateFiles(hostOptions.modifiedFiles); diff --git a/packages/angular/build/src/tools/angular/compilation/typescript-compilation.ts b/packages/angular/build/src/tools/angular/compilation/typescript-compilation.ts index 970041f916fc..71061031f3a4 100644 --- a/packages/angular/build/src/tools/angular/compilation/typescript-compilation.ts +++ b/packages/angular/build/src/tools/angular/compilation/typescript-compilation.ts @@ -12,8 +12,16 @@ import ts from 'typescript'; import { toPosixPath } from '../../../utils/path'; import { profileAsync, profileSync } from '../../esbuild/profiling'; import { AngularCompilation, DiagnosticModes } from './angular-compilation'; +import { type CompilerOptionOverrides, transformCompilerOptions } from './compiler-options'; import { convertTypeScriptDiagnostic } from './diagnostics'; +export interface TransformedConfiguration { + compilerOptions: ng.CompilerOptions; + rootNames: string[]; + errors: ts.Diagnostic[]; + warnings: PartialMessage[]; +} + export abstract class TypeScriptCompilation extends AngularCompilation { static #angularCompilerCliModule?: typeof ng; @@ -23,10 +31,17 @@ export abstract class TypeScriptCompilation extends AngularCompilation { return TypeScriptCompilation.#angularCompilerCliModule; } - protected async loadConfiguration(tsconfig: string): Promise { + protected async loadConfiguration( + tsconfig: string, + compilerOptionOverrides?: CompilerOptionOverrides, + ): Promise { const { readConfiguration } = await TypeScriptCompilation.loadCompilerCli(); - return profileSync('NG_READ_CONFIG', () => + const { + options: originalCompilerOptions, + rootNames, + errors, + } = profileSync('NG_READ_CONFIG', () => readConfiguration(tsconfig, { // Angular specific configuration defaults and overrides to ensure a functioning compilation. suppressOutputPathCheck: true, @@ -44,6 +59,20 @@ export abstract class TypeScriptCompilation extends AngularCompilation { removeComments: false, }), ); + + const { compilerOptions, warnings } = transformCompilerOptions( + ts, + originalCompilerOptions, + compilerOptionOverrides, + tsconfig, + ); + + return { + compilerOptions, + rootNames, + errors, + warnings, + }; } protected readonly sourceFiles = new Map();