Command
Is this a regression?
Yes.
The previous version in which this bug was not present was
22.1.x (watchpack). Broken from 22.2.0-next.3.
Description
Repo layout: a shared TypeScript folder sits next to the Angular workspace. The workspace reaches it through a directory symlink. preserveSymlinks is true on the application builder.
The first build succeeds. After that, edits in the real folder (the symlink target) do not trigger a rebuild. New files and new exports are also ignored until ng serve / ng build --watch is restarted.
This is the same layout as #23896. Webpack was fixed in #23900 by setting watchpack followSymlinks when preserveSymlinks is on.
22.2.0-next.3 replaced watchpack with @parcel/watcher (a6ef9cf). createWatcher still gets followSymlinks: preserveSymlinks, but only the chokidar polling fallback uses that option. The default Parcel path never reads it.
Parcel subscribes to the workspace root. Native watchers do not recurse through a directory symlink that points outside that root. With preserveSymlinks: true, esbuild reports watch files as the symlink paths inside the workspace, so the extra outside-root subscription also never attaches to the real folder.
--poll works, because that path uses chokidar with followSymlinks.
Minimal Reproduction
repo/
model/
index.ts
app/
libs/model -> ../../model
angular.json # builder @angular/build:application, preserveSymlinks: true
tsconfig.json # paths: { "@shared/model": ["./libs/model"] }
- Import
@shared/model from the app.
- Run
ng serve (or ng build --watch).
- Change
model/index.ts.
- The watcher does not rebuild.
Exception or Error
None. The watcher stays idle.
Your Environment
Angular CLI: 22.2.0-next.6
@angular/build: 22.2.0-next.6
Angular: 22.1.0
Builder: @angular/build:application
OS: darwin arm64
Anything else relevant?
Related: #23896, #23900, #25753, #15100.
In 22.2.0-next.6:
packages/angular/build/src/builders/application/build-action.ts passes followSymlinks: preserveSymlinks.
packages/angular/build/src/tools/esbuild/watcher.ts: createParcelWatcher ignores options.followSymlinks; createChokidarWatcher sets it.
A fix that matches the old watchpack behaviour: when followSymlinks is true, realpath watch files that sit behind a directory symlink and subscribe Parcel to those real directories.
Command
--watch)Is this a regression?
Yes.
The previous version in which this bug was not present was
22.1.x(watchpack). Broken from22.2.0-next.3.Description
Repo layout: a shared TypeScript folder sits next to the Angular workspace. The workspace reaches it through a directory symlink.
preserveSymlinksistrueon the application builder.The first build succeeds. After that, edits in the real folder (the symlink target) do not trigger a rebuild. New files and new exports are also ignored until
ng serve/ng build --watchis restarted.This is the same layout as #23896. Webpack was fixed in #23900 by setting watchpack
followSymlinkswhenpreserveSymlinksis on.22.2.0-next.3replaced watchpack with@parcel/watcher(a6ef9cf).createWatcherstill getsfollowSymlinks: preserveSymlinks, but only the chokidar polling fallback uses that option. The default Parcel path never reads it.Parcel subscribes to the workspace root. Native watchers do not recurse through a directory symlink that points outside that root. With
preserveSymlinks: true, esbuild reports watch files as the symlink paths inside the workspace, so the extra outside-root subscription also never attaches to the real folder.--pollworks, because that path uses chokidar withfollowSymlinks.Minimal Reproduction
@shared/modelfrom the app.ng serve(orng build --watch).model/index.ts.Exception or Error
None. The watcher stays idle.
Your Environment
Anything else relevant?
Related: #23896, #23900, #25753, #15100.
In
22.2.0-next.6:packages/angular/build/src/builders/application/build-action.tspassesfollowSymlinks: preserveSymlinks.packages/angular/build/src/tools/esbuild/watcher.ts:createParcelWatcherignoresoptions.followSymlinks;createChokidarWatchersets it.A fix that matches the old watchpack behaviour: when
followSymlinksis true, realpath watch files that sit behind a directory symlink and subscribe Parcel to those real directories.