Skip to content

Commit e827c69

Browse files
committed
fix(@angular-devkit/build-angular): watch all bundler provided inputs with esbuild builder
When using the esbuild-based browser application builder in watch mode (including `ng serve`), all input files provided by the bundler via the internal metafile information will now be watched and will trigger rebuilds if changed. This allows for files outside of the TypeScript compilation that are also outside of the project source root to be watched. This situation can be encountered in monorepo setups where library code is directly referenced within an application.
1 parent 1bbac6a commit e827c69

File tree

4 files changed

+27
-4
lines changed

4 files changed

+27
-4
lines changed

packages/angular_devkit/build_angular/src/tools/esbuild/angular/aot-compilation.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,10 @@ export class AotCompilation extends AngularCompilation {
103103
const referencedFiles = typeScriptProgram
104104
.getSourceFiles()
105105
.filter((sourceFile) => !angularCompiler.ignoreForEmit.has(sourceFile))
106-
.map((sourceFile) => sourceFile.fileName);
106+
.flatMap((sourceFile) => [
107+
sourceFile.fileName,
108+
...angularCompiler.getResourceDependencies(sourceFile),
109+
]);
107110

108111
return { affectedFiles, compilerOptions, referencedFiles };
109112
}

packages/angular_devkit/build_angular/src/tools/esbuild/bundler-context.ts

+14-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import {
1616
build,
1717
context,
1818
} from 'esbuild';
19-
import { basename, extname, relative } from 'node:path';
19+
import { basename, extname, join, relative } from 'node:path';
2020

2121
export type BundleContextResult =
2222
| { errors: Message[]; warnings: Message[] }
@@ -48,6 +48,8 @@ export class BundlerContext {
4848
#esbuildContext?: BuildContext<{ metafile: true; write: false }>;
4949
#esbuildOptions: BuildOptions & { metafile: true; write: false };
5050

51+
readonly watchFiles = new Set<string>();
52+
5153
constructor(
5254
private workspaceRoot: string,
5355
private incremental: boolean,
@@ -138,6 +140,17 @@ export class BundlerContext {
138140
}
139141
}
140142

143+
// Update files that should be watched.
144+
// While this should technically not be linked to incremental mode, incremental is only
145+
// currently enabled with watch mode where watch files are needed.
146+
if (this.incremental) {
147+
this.watchFiles.clear();
148+
// Add input files except virtual angular files which do not exist on disk
149+
Object.keys(result.metafile.inputs)
150+
.filter((input) => !input.startsWith('angular:'))
151+
.forEach((input) => this.watchFiles.add(join(this.workspaceRoot, input)));
152+
}
153+
141154
// Return if the build encountered any errors
142155
if (result.errors.length) {
143156
return {

packages/angular_devkit/build_angular/src/tools/esbuild/bundler-execution-result.ts

+6-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,12 @@ export class ExecutionResult {
4949
}
5050

5151
get watchFiles() {
52-
return this.codeBundleCache?.referencedFiles ?? [];
52+
const files = this.rebuildContexts.flatMap((context) => [...context.watchFiles]);
53+
if (this.codeBundleCache?.referencedFiles) {
54+
files.push(...this.codeBundleCache.referencedFiles);
55+
}
56+
57+
return files;
5358
}
5459

5560
createRebuildState(fileChanges: ChangedFiles): RebuildState {

packages/angular_devkit/build_angular/src/tools/esbuild/watcher.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,9 @@ export function createWatcher(options?: {
3636
ignored?: string[];
3737
}): BuildWatcher {
3838
const watcher = new FSWatcher({
39-
...options,
39+
usePolling: options?.polling,
40+
interval: options?.interval,
41+
ignored: options?.ignored,
4042
disableGlobbing: true,
4143
ignoreInitial: true,
4244
});

0 commit comments

Comments
 (0)