Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(@angular-devkit/build-angular): add initial watch support to esb…
…uild-based builder The experimental esbuild-based browser application builder now contains initial support for watching input files and rebuilding the application via the `--watch` option. This initial implemention is not yet optimized for incremental rebuilds and will perform a full rebuild upon detection of a change. Incremental rebuild support will be added in followup changes and will significantly improve the rebuild speed. The `chokidar` npm package is used to perform the file watching which allows for native file- system event based watching. Polling is also support via the `--poll` option for environments that require it.
- Loading branch information
Showing
7 changed files
with
207 additions
and
57 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
110 changes: 110 additions & 0 deletions
110
packages/angular_devkit/build_angular/src/builders/browser-esbuild/watcher.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
/** | ||
* @license | ||
* Copyright Google LLC All Rights Reserved. | ||
* | ||
* Use of this source code is governed by an MIT-style license that can be | ||
* found in the LICENSE file at https://angular.io/license | ||
*/ | ||
|
||
import { FSWatcher } from 'chokidar'; | ||
|
||
export class ChangedFiles { | ||
readonly added = new Set<string>(); | ||
readonly modified = new Set<string>(); | ||
readonly removed = new Set<string>(); | ||
|
||
toDebugString(): string { | ||
const content = { | ||
added: Array.from(this.added), | ||
modified: Array.from(this.modified), | ||
removed: Array.from(this.removed), | ||
}; | ||
|
||
return JSON.stringify(content, null, 2); | ||
} | ||
} | ||
|
||
export interface BuildWatcher extends AsyncIterableIterator<ChangedFiles> { | ||
add(paths: string | string[]): void; | ||
remove(paths: string | string[]): void; | ||
close(): Promise<void>; | ||
} | ||
|
||
export function createWatcher(options?: { | ||
polling?: boolean; | ||
interval?: number; | ||
ignored?: string[]; | ||
}): BuildWatcher { | ||
const watcher = new FSWatcher({ | ||
...options, | ||
disableGlobbing: true, | ||
ignoreInitial: true, | ||
}); | ||
|
||
const nextQueue: ((value?: ChangedFiles) => void)[] = []; | ||
let currentChanges: ChangedFiles | undefined; | ||
|
||
watcher.on('all', (event, path) => { | ||
switch (event) { | ||
case 'add': | ||
currentChanges ??= new ChangedFiles(); | ||
currentChanges.added.add(path); | ||
break; | ||
case 'change': | ||
currentChanges ??= new ChangedFiles(); | ||
currentChanges.modified.add(path); | ||
break; | ||
case 'unlink': | ||
currentChanges ??= new ChangedFiles(); | ||
currentChanges.removed.add(path); | ||
break; | ||
default: | ||
return; | ||
} | ||
|
||
const next = nextQueue.shift(); | ||
if (next) { | ||
const value = currentChanges; | ||
currentChanges = undefined; | ||
next(value); | ||
} | ||
}); | ||
|
||
return { | ||
[Symbol.asyncIterator]() { | ||
return this; | ||
}, | ||
|
||
async next() { | ||
if (currentChanges && nextQueue.length === 0) { | ||
const result = { value: currentChanges }; | ||
currentChanges = undefined; | ||
|
||
return result; | ||
} | ||
|
||
return new Promise((resolve) => { | ||
nextQueue.push((value) => resolve(value ? { value } : { done: true, value })); | ||
}); | ||
}, | ||
|
||
add(paths) { | ||
watcher.add(paths); | ||
}, | ||
|
||
remove(paths) { | ||
watcher.unwatch(paths); | ||
}, | ||
|
||
async close() { | ||
try { | ||
await watcher.close(); | ||
} finally { | ||
let next; | ||
while ((next = nextQueue.shift()) !== undefined) { | ||
next(); | ||
} | ||
} | ||
}, | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters