From 596f7639a6c7fe00c9088e32739578cc374a31e2 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Tue, 14 Nov 2023 17:01:18 -0500 Subject: [PATCH] fix(@angular-devkit/build-angular): ensure compilation errors propagate to all bundle actions If the TypeScript and/or Angular AOT compiler fails to initialize or emit files due to an error, the shared compilation state between the browser code bundle action and any additional bundle actions (polyfills, server, etc.) will now carry an error flag to ensure that the additional bundle actions bypass file emit. The file emit bypass is necessary in these cases to prevent an unintentional and misleading error about a file not being included in the compilation. (cherry picked from commit 38b7667ce35ad96c681f6136e2dd2dceec4a2961) --- .../tools/esbuild/angular/compilation-state.ts | 16 +++++++++------- .../src/tools/esbuild/angular/compiler-plugin.ts | 7 +++---- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/packages/angular_devkit/build_angular/src/tools/esbuild/angular/compilation-state.ts b/packages/angular_devkit/build_angular/src/tools/esbuild/angular/compilation-state.ts index 6b8aa0381a32..5940c9454ab8 100644 --- a/packages/angular_devkit/build_angular/src/tools/esbuild/angular/compilation-state.ts +++ b/packages/angular_devkit/build_angular/src/tools/esbuild/angular/compilation-state.ts @@ -8,12 +8,13 @@ export class SharedTSCompilationState { #pendingCompilation = true; - #resolveCompilationReady: (() => void) | undefined; - #compilationReadyPromise: Promise | undefined; + #resolveCompilationReady: ((value: boolean) => void) | undefined; + #compilationReadyPromise: Promise | undefined; + #hasErrors = true; - get waitUntilReady(): Promise { + get waitUntilReady(): Promise { if (!this.#pendingCompilation) { - return Promise.resolve(); + return Promise.resolve(this.#hasErrors); } this.#compilationReadyPromise ??= new Promise((resolve) => { @@ -23,8 +24,9 @@ export class SharedTSCompilationState { return this.#compilationReadyPromise; } - markAsReady(): void { - this.#resolveCompilationReady?.(); + markAsReady(hasErrors: boolean): void { + this.#hasErrors = hasErrors; + this.#resolveCompilationReady?.(hasErrors); this.#compilationReadyPromise = undefined; this.#pendingCompilation = false; } @@ -34,7 +36,7 @@ export class SharedTSCompilationState { } dispose(): void { - this.markAsReady(); + this.markAsReady(true); globalSharedCompilationState = undefined; } } diff --git a/packages/angular_devkit/build_angular/src/tools/esbuild/angular/compiler-plugin.ts b/packages/angular_devkit/build_angular/src/tools/esbuild/angular/compiler-plugin.ts index 9ddc95f7d114..102d674db127 100644 --- a/packages/angular_devkit/build_angular/src/tools/esbuild/angular/compiler-plugin.ts +++ b/packages/angular_devkit/build_angular/src/tools/esbuild/angular/compiler-plugin.ts @@ -263,8 +263,7 @@ export function createCompilerPlugin( } if (compilation instanceof NoopCompilation) { - await sharedTSCompilationState.waitUntilReady; - hasCompilationErrors = false; + hasCompilationErrors = await sharedTSCompilationState.waitUntilReady; return result; } @@ -318,7 +317,7 @@ export function createCompilerPlugin( // Reset the setup warnings so that they are only shown during the first build. setupWarnings = undefined; - sharedTSCompilationState.markAsReady(); + sharedTSCompilationState.markAsReady(hasCompilationErrors); return result; }); @@ -409,7 +408,7 @@ export function createCompilerPlugin( build.onEnd((result) => { // Ensure other compilations are unblocked if the main compilation throws during start - sharedTSCompilationState?.markAsReady(); + sharedTSCompilationState?.markAsReady(hasCompilationErrors); for (const { outputFiles, metafile } of additionalResults.values()) { // Add any additional output files to the main output files