Watch mode (`ng test`, `ng serve`) stalls after "Watch mode enabled" when `preserveSymlinks: true` — chokidar scans entire workspace incl. `node_modules` (regression in 22.2.0)
Mantenedores costumam responder em até 1 dia
Ninguém assumiu esta issue ainda.
Avaliação
- Dificuldade
- 4/5
- Tempo estimado
- 3-5 dias
- Facilidade para iniciantes
- 58/100
- Tipo de issue
- Bug
- Clareza
- Razoavelmente clara
- Status de atividade
- Ativa
- Stack de tecnologia
- angular, typescript
- Domínio
- build-system, cli, testing-qa
Direção de pesquisa
Start in src/builders/application/build-action.js and src/utils/watcher.js, tracing setupWatcher(), createWatcher(), and createChokidarWatcher() for preserveSymlinks: true. Use the linked reproduction or the listed npx and ng test commands on Windows, then verify that ng test, ng serve, and ng build --watch no longer wait on an unnecessarily broad initial scan before the first result.
Escrita pelo modelo de indexação a partir do texto da issue.
Descrição
Command
- test
- serve
Is this a regression?
- Yes, this behavior used to work in the previous version
The previous version in which this bug was not present was
22.1.8
Description
(AI generated)
After updating @angular/build / @angular/cli from 22.1.8 to 22.2.0, ng test in watch mode (@angular/build:unit-test, Vitest runner) no longer starts running tests after the initial build when the build target has "preserveSymlinks": true. The output stops at:
Application bundle generation complete. [52.899 seconds]
Watch mode enabled. Watching for file changes...
With NG_TEST_LOG=1, VitestExecutor never logs Executing test run — the first build result is not handed to the executor. We stopped the process after more than 4 minutes of waiting. ng test --watch=false is unaffected (the full suite finishes in ~3 min including the build).
Setting "preserveSymlinks": false in the test build configuration makes Vitest start ~2 s after the build completes. Downgrading Vitest (5.0.1 → 4.1.11) makes no difference, so it is not Vitest-related.
Cause (from reading @angular/build 22.2.0 sources):
In src/builders/application/build-action.js, watch mode now calls setupWatcher() from src/utils/watcher.js before emitting the first build result:
createWatcher()uses chokidar instead of@parcel/watcherwheneverfollowSymlinks(=preserveSymlinks) is true.createChokidarWatcher()callschokidar.watch(rootDir, …)on the entire workspace root (cwd: workspaceRoot), regardless ofNG_BUILD_WATCH_ROOT.- The
**/node_modules/**ignore pattern is only added whenshouldWatchRoot && !preserveSymlinks, so withpreserveSymlinks: truechokidar also walks all ofnode_modules(≈106 000 files in our workspace). - It then does
await once(watcher, 'ready')(added in #34122), i.e. it blocks until that full initial scan has completed — withfollowSymlinks: trueon Windows.
In 22.1.8, build-action.js used tools/esbuild/watcher.js and only watched the files/directories from result.watchFiles (plus the project root only if NG_BUILD_WATCH_ROOT was set), with no wait for an initial scan, so startup was instant.
preserveSymlinks: true is a common setting for workspaces that npm link local libraries, so this effectively makes watch mode unusable for them.
Since ng serve and ng build --watch go through the same runEsBuildBuildAction / setupWatcher path, they are affected as well, see comment below.
Possible fixes:
- Keep watching only
watchFiles(and the root only withNG_BUILD_WATCH_ROOT), as in 22.1.8, for the chokidar path; or - ignore
node_modulesunder the workspace root in the chokidar path as well — explicitly added watch files outside the root (e.g.npm linktargets) would still be watched; or - don't block the first build result on chokidar's
readywhen the initial scan is large.
Minimal Reproduction
Verified by me (human): https://github.com/reifi/angular-preserve-symlinks-watch-repro
Reproducible with a freshly generated project:
npx @angular/[email protected] new repro --defaults --test-runner=vitest- In
angular.json, add"preserveSymlinks": truetoprojects.repro.architect.build.options. - Run
ng test(watch mode;ng test --watchin a non-TTY shell). - Observe: output stops after "Watch mode enabled. Watching for file changes..." for about 2 minutes before Vitest starts.
Measured on Windows 11, fresh project (≈18 000 files in node_modules), time from "Watch mode enabled" to the Vitest test summary:
preserveSymlinks |
Time to test summary | Vitest run duration |
|---|---|---|
| not set (default) | 6 s | 5.3 s |
true |
123 s | 7.0 s |
The delay scales with the number of files under the workspace root. In a large application workspace (≈106 000 files in node_modules) tests had still not started after more than 4 minutes, when we stopped the process. ng test --watch=false is not affected.
Exception or Error
No error — the process hangs silently after:
Watch mode enabled. Watching for file changes...
Your Environment
_ _ ____ _ ___
/ \ _ __ __ _ _ _| | __ _ _ __ / ___| | |_ _|
/ △ \ | '_ \ / _` | | | | |/ _` | '__| | | | | | |
/ ___ \| | | | (_| | |_| | | (_| | | | |___| |___ | |
/_/ \_\_| |_|\__, |\__,_|_|\__,_|_| \____|_____|___|
|___/
Angular CLI : 22.2.0
Angular : 22.2.0
Node.js : 26.8.2
Package Manager : npm 11.19.1
Operating System : win32 x64
┌─────────────────────────────────┬───────────────────┬───────────────────┐
│ Package │ Installed Version │ Requested Version │
├─────────────────────────────────┼───────────────────┼───────────────────┤
│ @angular/build │ 22.2.0 │ ^22.2.0 │
│ @angular/cdk │ 22.2.0 │ ^22.2.0 │
│ @angular/cli │ 22.2.0 │ ^22.2.0 │
│ @angular/common │ 22.2.0 │ ^22.2.0 │
│ @angular/compiler │ 22.2.0 │ ^22.2.0 │
│ @angular/compiler-cli │ 22.2.0 │ ^22.2.0 │
│ @angular/core │ 22.2.0 │ ^22.2.0 │
│ @angular/forms │ 22.2.0 │ ^22.2.0 │
│ @angular/google-maps │ 22.2.0 │ ^22.2.0 │
│ @angular/localize │ 22.2.0 │ ^22.2.0 │
│ @angular/material │ 22.2.0 │ ^22.2.0 │
│ @angular/material-luxon-adapter │ 22.2.0 │ ^22.2.0 │
│ @angular/platform-browser │ 22.2.0 │ ^22.2.0 │
│ @angular/router │ 22.2.0 │ ^22.2.0 │
│ @angular/upgrade │ 22.2.0 │ ^22.2.0 │
│ rxjs │ 7.8.2 │ ^7.8.2 │
│ typescript │ 6.0.3 │ ^6.0.3 │
│ vitest │ 5.0.1 │ ^5.0.1 │
│ zone.js │ 0.16.3 │ ^0.16.3 │
└─────────────────────────────────┴───────────────────┴───────────────────┘
Anything else relevant?
Workaround: override "preserveSymlinks": false in the build configuration referenced by the unit-test buildTarget, e.g.
"configurations": {
"test": {
"preserveSymlinks": false,
…
}
}
The unit-test builder reads preserveSymlinks from the build target options (unit-test/options.js), so this only affects tests; ng serve / ng build keep preserveSymlinks: true for npm link.
- Linguagem predominante
- TypeScript
- Estrelas
- 27k
- Forks
- 11.8k
- Merge médio
- 21h 32min
- PRs com merge (30d)
- 162
Preparar o ambiente
Primeiros passos
- Leia a issue inteira e depois o guia de contribuição do projeto.
- Comente na issue dizendo que vai assumir — evita que duas pessoas façam o mesmo trabalho.
- Faça um fork do repositório e trabalhe em uma branch.
- Abra um pull request que referencie o número da issue.
Mais de angular/angular-cli
-
area: @angular/build gemini-triaged
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 74/100
angular/angular-cli#33955 ·
Mantenedores costumam responder em até 1 dia
-
area: @angular/cli gemini-triaged
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 72/100
angular/angular-cli#33055 · 1 comentário · 3 reações ·
Mantenedores costumam responder em até 1 dia
-
area: @angular-devkit/build-angular gemini-triaged
Dificuldade 3/5 1-2 dias Facilidade para iniciantes 68/100
angular/angular-cli#34195 ·
Mantenedores costumam responder em até 1 dia
-
library builder: tslib is not added to the output package.jsonTalvez já em andamento @alan-agius4 assumiu há 9 dias. Abertaangular/build:library area: @angular/build gemini-triaged
angular/angular-cli#34131 · 1 responsável ·
Mantenedores costumam responder em até 1 dia
-
library builder: a name re-exported through two "export *" paths is dropped from the bundleTalvez já em andamento @alan-agius4 assumiu há 9 dias. Abertaangular/build:library area: @angular/build gemini-triaged
angular/angular-cli#34130 · 1 responsável ·
Mantenedores costumam responder em até 1 dia
Todas as issues de angular/angular-cli
Issues semelhantes
-
priority: P2
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 78/100
-
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 65/100
prime-radiant-inc/evener#3291 ·
Mantenedores costumam responder em até 1 dia
-
accessibility bug revealjs
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 84/100
quarto-dev/quarto-cli#14961 ·
Mantenedores costumam responder em até 1 dia
-
Dificuldade 1/5 Menos de uma hora Facilidade para iniciantes 90/100
supabase/agent-skills#614 ·
-
Content
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 68/100
RunestoneInteractive/rs#1559 · 1 comentário ·
Mantenedores costumam responder em até 2 dias