@@ -95,62 +95,71 @@ export async function* runEsBuildBuildAction(
9595 }
9696 }
9797
98- // Setup watcher if watch mode enabled
9998 let watcher : import ( '../../tools/esbuild/watcher' ) . BuildWatcher | undefined ;
100- if ( watch ) {
101- if ( progress ) {
102- logger . info ( 'Watch mode enabled. Watching for file changes...' ) ;
103- }
99+ let watchLoopStarted = false ;
100+ try {
101+ // Setup watcher if watch mode enabled
102+ if ( watch ) {
103+ if ( progress ) {
104+ logger . info ( 'Watch mode enabled. Watching for file changes...' ) ;
105+ }
106+
107+ const ignored : string [ ] = [
108+ // Ignore the output and cache paths to avoid infinite rebuild cycles
109+ outputOptions . base ,
110+ cacheOptions . basePath ,
111+ `${ toPosixPath ( workspaceRoot ) } /**/.*/**` ,
112+ ] ;
113+
114+ // Setup a watcher
115+ const { createWatcher } = await import ( '../../tools/esbuild/watcher' ) ;
116+ watcher = createWatcher ( {
117+ polling : typeof poll === 'number' ,
118+ interval : poll ,
119+ followSymlinks : preserveSymlinks ,
120+ ignored,
121+ } ) ;
122+
123+ // Setup abort support
124+ options . signal ?. addEventListener ( 'abort' , ( ) => void watcher ?. close ( ) ) ;
125+
126+ // Watch the entire project root if 'NG_BUILD_WATCH_ROOT' environment variable is set
127+ if ( shouldWatchRoot ) {
128+ if ( ! preserveSymlinks ) {
129+ // Ignore all node modules directories to avoid excessive file watchers.
130+ // Package changes are handled below by watching manifest and lock files.
131+ // NOTE: this is not enable when preserveSymlinks is true as this would break `npm link` usages.
132+ ignored . push ( '**/node_modules/**' ) ;
133+
134+ watcher . add (
135+ packageWatchFiles
136+ . map ( ( file ) => path . join ( workspaceRoot , file ) )
137+ . filter ( ( file ) => existsSync ( file ) ) ,
138+ ) ;
139+ }
104140
105- const ignored : string [ ] = [
106- // Ignore the output and cache paths to avoid infinite rebuild cycles
107- outputOptions . base ,
108- cacheOptions . basePath ,
109- `${ toPosixPath ( workspaceRoot ) } /**/.*/**` ,
110- ] ;
111-
112- // Setup a watcher
113- const { createWatcher } = await import ( '../../tools/esbuild/watcher' ) ;
114- watcher = createWatcher ( {
115- polling : typeof poll === 'number' ,
116- interval : poll ,
117- followSymlinks : preserveSymlinks ,
118- ignored,
119- } ) ;
120-
121- // Setup abort support
122- options . signal ?. addEventListener ( 'abort' , ( ) => void watcher ?. close ( ) ) ;
123-
124- // Watch the entire project root if 'NG_BUILD_WATCH_ROOT' environment variable is set
125- if ( shouldWatchRoot ) {
126- if ( ! preserveSymlinks ) {
127- // Ignore all node modules directories to avoid excessive file watchers.
128- // Package changes are handled below by watching manifest and lock files.
129- // NOTE: this is not enable when preserveSymlinks is true as this would break `npm link` usages.
130- ignored . push ( '**/node_modules/**' ) ;
131-
132- watcher . add (
133- packageWatchFiles
134- . map ( ( file ) => path . join ( workspaceRoot , file ) )
135- . filter ( ( file ) => existsSync ( file ) ) ,
136- ) ;
141+ watcher . add ( projectRoot ) ;
137142 }
138143
139- watcher . add ( projectRoot ) ;
144+ // Watch locations provided by the initial build result
145+ watcher . add ( result . watchFiles ) ;
140146 }
141147
142- // Watch locations provided by the initial build result
143- watcher . add ( result . watchFiles ) ;
144- }
148+ // Output the first build results after setting up the watcher to ensure that any code executed
149+ // higher in the iterator call stack will trigger the watcher. This is particularly relevant for
150+ // unit tests which execute the builder and modify the file system programmatically.
151+ yield * emitOutputResults ( result , outputOptions ) ;
145152
146- // Output the first build results after setting up the watcher to ensure that any code executed
147- // higher in the iterator call stack will trigger the watcher. This is particularly relevant for
148- // unit tests which execute the builder and modify the file system programmatically.
149- yield * emitOutputResults ( result , outputOptions ) ;
153+ // Finish if watch mode is not enabled
154+ if ( ! watcher ) {
155+ return ;
156+ }
150157
151- // Finish if watch mode is not enabled
152- if ( ! watcher ) {
153- return ;
158+ watchLoopStarted = true ;
159+ } finally {
160+ if ( ! watchLoopStarted && result ) {
161+ await result . dispose ( ) ;
162+ }
154163 }
155164
156165 // Used to force a full result on next rebuild if there were initial errors.
0 commit comments