Skip to content

Commit dc79270

Browse files
authored
fix(@angular/build): ensure chokidar watcher is ready before returning
When initializing chokidar.watch with ignoreInitial: true, files visited during the initial scan are treated as the initial baseline and do not emit change events. If createChokidarWatcher returns before the initial scan completes, subsequent file modifications made shortly after setup can be visited for the first time during the initial scan, causing the change event to be dropped.
1 parent 1860222 commit dc79270

2 files changed

Lines changed: 10 additions & 2 deletions

File tree

packages/angular/build/src/builders/dev-server/tests/behavior/build-errors_spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@ describeServeBuilder(executeDevServer, DEV_SERVER_BUILDER_INFO, (harness, setupT
3838
expectNoLog(logs, 'Unexpected character "EOF"');
3939
},
4040
],
41-
{ outputLogsOnFailure: false, timeout: 90_000 },
41+
{ outputLogsOnFailure: false },
4242
);
43-
}, 120_000);
43+
});
4444
});
4545
});

packages/angular/build/src/tools/esbuild/watcher.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
import type * as ParcelWatcher from '@parcel/watcher';
1010
import type * as Chokidar from 'chokidar';
11+
import { once } from 'node:events';
1112
import * as fs from 'node:fs';
1213
import * as path from 'node:path';
1314
import picomatch from 'picomatch';
@@ -663,8 +664,15 @@ async function createChokidarWatcher(
663664
usePolling: !!options?.polling,
664665
interval: options?.interval,
665666
});
667+
666668
const initTime = Date.now();
667669

670+
// Wait for the watcher to complete its initial filesystem scan before returning.
671+
// With `ignoreInitial: true`, any file visited during the initial scan is treated as the initial baseline
672+
// and will not emit 'add' or 'change' events. Awaiting 'ready' ensures that rapid file modifications
673+
// made right after watcher setup (e.g. in rebuild tests) are not swallowed as initial files.
674+
await once(watcher, 'ready');
675+
668676
const handleEvent = (type: 'added' | 'modified' | 'removed', rawPath: string) => {
669677
const posixPath = toPosixPathNormalized(rawPath);
670678
const lookupKey = toLookupKey(posixPath, isCaseSensitive);

0 commit comments

Comments
 (0)