diff --git a/packages/angular_devkit/build_angular/src/tools/esbuild/angular/aot-compilation.ts b/packages/angular_devkit/build_angular/src/tools/esbuild/angular/aot-compilation.ts index 84a59e40a7b9..1b203c18c5e4 100644 --- a/packages/angular_devkit/build_angular/src/tools/esbuild/angular/aot-compilation.ts +++ b/packages/angular_devkit/build_angular/src/tools/esbuild/angular/aot-compilation.ts @@ -103,7 +103,10 @@ export class AotCompilation extends AngularCompilation { const referencedFiles = typeScriptProgram .getSourceFiles() .filter((sourceFile) => !angularCompiler.ignoreForEmit.has(sourceFile)) - .map((sourceFile) => sourceFile.fileName); + .flatMap((sourceFile) => [ + sourceFile.fileName, + ...angularCompiler.getResourceDependencies(sourceFile), + ]); return { affectedFiles, compilerOptions, referencedFiles }; } diff --git a/packages/angular_devkit/build_angular/src/tools/esbuild/bundler-context.ts b/packages/angular_devkit/build_angular/src/tools/esbuild/bundler-context.ts index 50d38243f290..bf06b5c7a5d2 100644 --- a/packages/angular_devkit/build_angular/src/tools/esbuild/bundler-context.ts +++ b/packages/angular_devkit/build_angular/src/tools/esbuild/bundler-context.ts @@ -16,7 +16,7 @@ import { build, context, } from 'esbuild'; -import { basename, extname, relative } from 'node:path'; +import { basename, extname, join, relative } from 'node:path'; export type BundleContextResult = | { errors: Message[]; warnings: Message[] } @@ -48,6 +48,8 @@ export class BundlerContext { #esbuildContext?: BuildContext<{ metafile: true; write: false }>; #esbuildOptions: BuildOptions & { metafile: true; write: false }; + readonly watchFiles = new Set(); + constructor( private workspaceRoot: string, private incremental: boolean, @@ -138,6 +140,17 @@ export class BundlerContext { } } + // Update files that should be watched. + // While this should technically not be linked to incremental mode, incremental is only + // currently enabled with watch mode where watch files are needed. + if (this.incremental) { + this.watchFiles.clear(); + // Add input files except virtual angular files which do not exist on disk + Object.keys(result.metafile.inputs) + .filter((input) => !input.startsWith('angular:')) + .forEach((input) => this.watchFiles.add(join(this.workspaceRoot, input))); + } + // Return if the build encountered any errors if (result.errors.length) { return { 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 d08ba3fd7209..40e879ed2bbe 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 @@ -49,7 +49,12 @@ export class ExecutionResult { } get watchFiles() { - return this.codeBundleCache?.referencedFiles ?? []; + const files = this.rebuildContexts.flatMap((context) => [...context.watchFiles]); + if (this.codeBundleCache?.referencedFiles) { + files.push(...this.codeBundleCache.referencedFiles); + } + + return files; } createRebuildState(fileChanges: ChangedFiles): RebuildState { diff --git a/packages/angular_devkit/build_angular/src/tools/esbuild/watcher.ts b/packages/angular_devkit/build_angular/src/tools/esbuild/watcher.ts index 053f585b48f7..944430aac95a 100644 --- a/packages/angular_devkit/build_angular/src/tools/esbuild/watcher.ts +++ b/packages/angular_devkit/build_angular/src/tools/esbuild/watcher.ts @@ -36,7 +36,9 @@ export function createWatcher(options?: { ignored?: string[]; }): BuildWatcher { const watcher = new FSWatcher({ - ...options, + usePolling: options?.polling, + interval: options?.interval, + ignored: options?.ignored, disableGlobbing: true, ignoreInitial: true, });