diff --git a/packages/angular_devkit/build_angular/src/webpack/plugins/service-worker-plugin.ts b/packages/angular_devkit/build_angular/src/webpack/plugins/service-worker-plugin.ts index 8d556ae7e365..0098d47e1529 100644 --- a/packages/angular_devkit/build_angular/src/webpack/plugins/service-worker-plugin.ts +++ b/packages/angular_devkit/build_angular/src/webpack/plugins/service-worker-plugin.ts @@ -21,6 +21,12 @@ export class ServiceWorkerPlugin { apply(compiler: Compiler) { compiler.hooks.done.tapPromise('angular-service-worker', async ({ compilation }) => { + if (compilation.errors.length) { + // Don't generate a service worker if the compilation has errors. + // When there are errors some files will not be emitted which would cause other errors down the line such as readdir failures. + return; + } + const { projectRoot, root, baseHref = '', ngswConfigPath } = this.options; // We use the output path from the compilation instead of build options since during // localization the output path is modified to a temp directory. @@ -31,17 +37,25 @@ export class ServiceWorkerPlugin { throw new Error('Compilation output path cannot be empty.'); } - await augmentAppWithServiceWorker( - projectRoot, - root, - outputPath, - baseHref, - ngswConfigPath, - // eslint-disable-next-line @typescript-eslint/no-explicit-any - (compiler.inputFileSystem as any).promises, - // eslint-disable-next-line @typescript-eslint/no-explicit-any - (compiler.outputFileSystem as any).promises, - ); + try { + await augmentAppWithServiceWorker( + projectRoot, + root, + outputPath, + baseHref, + ngswConfigPath, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + (compiler.inputFileSystem as any).promises, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + (compiler.outputFileSystem as any).promises, + ); + } catch (error) { + compilation.errors.push( + new compilation.compiler.webpack.WebpackError( + `Failed to generate service worker - ${error instanceof Error ? error.message : error}`, + ), + ); + } }); } }