diff --git a/packages/angular_devkit/build_angular/src/builders/application/execute-build.ts b/packages/angular_devkit/build_angular/src/builders/application/execute-build.ts index bd1208e37aa9..963daa5e334e 100644 --- a/packages/angular_devkit/build_angular/src/builders/application/execute-build.ts +++ b/packages/angular_devkit/build_angular/src/builders/application/execute-build.ts @@ -146,6 +146,8 @@ export async function executeBuild( // Return if the bundling has errors if (bundlingResult.errors) { + executionResult.addErrors(bundlingResult.errors); + return executionResult; } diff --git a/packages/angular_devkit/build_angular/src/builders/dev-server/vite-server.ts b/packages/angular_devkit/build_angular/src/builders/dev-server/vite-server.ts index 4e42a1b3b194..7afd7246a1b8 100644 --- a/packages/angular_devkit/build_angular/src/builders/dev-server/vite-server.ts +++ b/packages/angular_devkit/build_angular/src/builders/dev-server/vite-server.ts @@ -115,6 +115,7 @@ export async function* serveWithVite( let server: ViteDevServer | undefined; let listeningAddress: AddressInfo | undefined; + let hadError = false; const generatedFiles = new Map(); const assetFiles = new Map(); const build = @@ -134,6 +135,29 @@ export async function* serveWithVite( )) { assert(result.outputFiles, 'Builder did not provide result files.'); + // If build failed, nothing to serve + if (!result.success) { + // If server is active, send an error notification + if (result.errors?.length && server) { + hadError = true; + server.ws.send({ + type: 'error', + err: { + message: result.errors[0].text, + stack: '', + loc: result.errors[0].location, + }, + }); + } + continue; + } else if (hadError && server) { + // Send an empty update to clear the error overlay + server.ws.send({ + 'type': 'update', + updates: [], + }); + } + // Analyze result files for changes analyzeResultFiles(normalizePath, htmlIndexPath, result.outputFiles, generatedFiles); diff --git a/packages/angular_devkit/build_angular/src/tools/esbuild/bundler-execution-result.ts b/packages/angular_devkit/build_angular/src/tools/esbuild/bundler-execution-result.ts index 877676eec93d..55840967d48d 100644 --- a/packages/angular_devkit/build_angular/src/tools/esbuild/bundler-execution-result.ts +++ b/packages/angular_devkit/build_angular/src/tools/esbuild/bundler-execution-result.ts @@ -6,6 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ +import type { Message } from 'esbuild'; import type { ChangedFiles } from '../../tools/esbuild/watcher'; import type { SourceFileCache } from './angular/source-file-cache'; import type { BuildOutputFile, BuildOutputFileType, BundlerContext } from './bundler-context'; @@ -28,6 +29,7 @@ export interface RebuildState { export class ExecutionResult { outputFiles: BuildOutputFile[] = []; assetFiles: BuildOutputAsset[] = []; + errors: Message[] = []; constructor( private rebuildContexts: BundlerContext[], @@ -42,17 +44,22 @@ export class ExecutionResult { this.assetFiles.push(...assets); } + addErrors(errors: Message[]): void { + this.errors.push(...errors); + } + get output() { return { - success: this.outputFiles.length > 0, + success: this.errors.length === 0, }; } get outputWithFiles() { return { - success: this.outputFiles.length > 0, + success: this.errors.length === 0, outputFiles: this.outputFiles, assetFiles: this.assetFiles, + errors: this.errors, }; }