Repository navigation
fix(@angular/build): resolve unimported NgModule scopes when filtering unit-test files - #34329
Merged
dgp1130 merged 1 commit intoOct 14, 2026
Merged
Conversation
…g unit-test files When `rootFiles` overrides are provided (such as during `unit-test` runs), the initial TypeScript program is restricted to those entry points and their transitive imports. If a test imports a non-standalone `@Component` directly without importing its declaring `@NgModule`, the `NgModule` may be omitted from the program and leave the component without its compilation scope. Preserve the full `tsconfig` root file set as `fallbackRootNames` for application builds when `rootFiles` is a subset of the `tsconfig` files. If AOT analysis detects a non-standalone component lacking an owning `NgModule` scope (`getOwningNgModule(component) === null`) and additional uncompiled `tsconfig` files exist, recreate and re-analyze the Angular program with the full root file set so all `NgModule` declarations can be discovered.
clydin
force-pushed
the
fix/unit-test-ngmodule-scope-fallback
branch
from
October 13, 2026 16:56
6be51ea to
957de2a
Compare
clydin
marked this pull request as ready for review
October 13, 2026 18:47
There was a problem hiding this comment.
Code Review
This pull request introduces a fallback mechanism to the full tsconfig root file set (fallbackRootNames) during AOT compilation when explicit rootFiles filtering is active. This fallback is triggered if a non-standalone component is encountered that lacks a resolved NgModule scope, allowing the Angular compiler to discover all NgModules and resolve component compilation scopes. Unit tests have been added to verify this behavior. I have no additional feedback to provide as there are no review comments.
1 task done
alan-agius4
approved these changes
Oct 14, 2026
Collaborator
|
This PR was merged into the repository. The changes were merged into the following branches:
|
leosvelperez
added a commit
to nrwl/nx
that referenced
this pull request
Oct 19, 2026
The @angular/build 22.2 Vitest runner skips NgModule files that no spec imports, so both NgRx e2e tests fail with NG8001 (angular/angular-cli#34231). The fix, angular/angular-cli#34329, is on main but not in a 22.2.x release yet.
FrozenPandaz
pushed a commit
to nrwl/nx
that referenced
this pull request
Oct 19, 2026
## Current Behavior Nx creates Angular workspaces with Angular 22.1 and has no migration to 22.2. With Angular 22.2: - `@nx/angular-rspack` doesn't work with `@angular/build` 22.2, because the private Angular APIs it calls changed. - Vitest runs that use Analog before 2.7.3 fail with `cache.has is not a function`. - Buildable libraries built with ng-packagr 22.2.0 to 22.2.3 are missing the output of their secondary entry points. - A secondary entry point with its own browserslist file gets different CSS targets than ng-packagr 22.2 gives it. Other `@nx/angular-rspack` bugs: - When `/` is prerendered, server responses have two `ng-state` scripts, because the server renders from the prerendered `/` page. - With `@angular/build` 22.1, `isolatedModules` and script source maps, some bundled files get empty source maps. - With `@angular/build` 22.1.3 or later, `3rdpartylicenses.txt` differs from the Angular CLI output. - With `@angular/build` before 22.2, `removeComments: true` in the tsconfig strips `/* @__PURE__ */` annotations, so the minifier keeps unused calls. The `add-trust-proxy-headers` migration breaks `new AngularAppEngine` written without parentheses. It adds a second `trustProxyHeaders` when the options set it with a shorthand, method or accessor member. ## Expected Behavior - New workspaces and generated projects install Angular `~22.2.0` and angular-eslint `^22.5.0`. New Vitest setups with Analog install Analog `~2.7.3`. - `nx migrate` moves Angular 22.1 workspaces to 22.2. Workspaces that use Angular Cypress component testing, or `@module-federation/enhanced` in an Angular webpack build, stay on 22.1, and the migration says why. - `nx migrate` moves Angular 22 workspaces to angular-eslint 22.5, and workspaces with Analog to Analog 2.7.3. - Setting up Cypress component testing fails on Angular 22.2 and later, with an error that links cypress-io/cypress#34259. - The `@nx/angular:unit-test` executor accepts Angular's new `splitting` option on 22.2 and rejects it on earlier versions. - `@nx/angular-rspack` works with `@angular/build` 22.2, where server-rendered and prerendered pages inline critical CSS like the Angular CLI. - The bugs listed above are fixed. ## Related Issue(s) Fixes #37375 NXC-5056 ## Implementation Notes > [!IMPORTANT] > Merge after #37477, which adds the `optionalUpdate` flag this PR sets on the Angular 22.2 update. Without it, `--include=required` runs the update and `--include=optional` skips it. - The Angular 22.2 update runs as a migration so it can keep a workspace on 22.1 when the first two breaks below affect it. - `add-angular-build` adds `@angular/build` at the installed `@angular-devkit/build-angular` version, so it doesn't run ahead of a workspace kept on 22.1. - `nx migrate` doesn't install after a migration that changes only catalog entries. #37478, released with this PR, fixes it. - For SSR, the browser build generates `index.server.html` and `index.csr.html` after output hashing, like the Angular CLI. On 22.2 the server index is written to `browser/index.original.html` for the Nx CommonEngine server template, so generated servers need no edits. - The repo catalog and the `@nx/webpack` option types move to webpack 5.111.0, with no runtime change. > [!IMPORTANT] > `@angular-devkit/build-angular` 22.2 installs webpack 5.111.0 and webpack-dev-server 6. No stable release fixes these breaks yet: > > - `@module-federation/enhanced` production builds fail (module-federation/core#5077, open fix in module-federation/core#5165). > - Cypress component testing rejects webpack-dev-server 6 (cypress-io/cypress#34259, open fix in cypress-io/cypress#35040). The Angular component testing e2e tests are skipped. > - Vitest tests of NgModule components can fail with NG8001 on `@angular/build` 22.2 (angular/angular-cli#34231, fixed by angular/angular-cli#34329 in 22.3.0-next.2). The `ngrx` e2e suite is skipped. > [!NOTE] > `useTsProjectReferences` has no effect on 22.2, and the plugin warns when it is set. A follow-up deprecates it for removal in Nx 25 and rewrites its `kb/create-config.mdoc` entry, which still says it enables project references. <!-- polygraph-session-start --> --- <p><a href="https://app.trypolygraph.com/orgs/6a061dcb561c062131116eca/sessions/nxc-5056-2dcb8260">View Polygraph session ↗</a></p> <!-- polygraph-session-end -->
4 of 10 tasks
eiweiss
added a commit
to cngxjs/cngx
that referenced
this pull request
Oct 21, 2026
…apps (#637) **feat(core/schematics): place the feedback outlets in ng new ngmodule apps** ### PR Type What kind of change does this PR introduce? - [ ] Bugfix - [x] Feature - [ ] Code style update (formatting, local variables) - [ ] Refactoring (no functional changes, no api changes) - [ ] Build related changes - [x] CI related changes - [x] Documentation content changes - [ ] Other... ### What is the current behavior? In an `ng new --standalone=false` app, `ng add @cngx/core` with feedback on places no outlet. The spec the CLI writes for an NgModule app declares `App` in its own TestBed, so `ng add` reads it as a custom spec, fails closed and only prints a note. ### What is the new behavior? On Angular CLI 21, `ng add` with feedback on places both outlets in an NgModule app and keeps `ng test` green: - `<cngx-banner-outlet />` and `<cngx-toast-outlet />` go into the root template, and `CngxBannerOutlet` and `CngxToastOutlet` into the root NgModule `imports`, as before for NgModule apps without a spec. - The untouched NgModule `app.spec.ts` gets both outlet classes in the TestBed `imports` (the property is created when it is missing), `provideFeedback(withToasts(), withBanners())` in its `providers`, and the two import statements. These are AST edits, re-checked at apply time. - Detection is exact: the scaffold catalog now holds the NgModule spec templates of CLI 21 and 22 (routing on or off, zone or zoneless, raw and Prettier-formatted), and the provided form is the same edit applied to those bodies, so a spec the CLI's Prettier pass reformatted still reads as provided. One changed character makes the spec custom. - A second `ng add` plans nothing. Angular 22 stays fail-closed. From `@angular/build` 22.2, the Vitest runner compiles only the specs and the files they import, so `App` compiles without `AppModule`. An untouched CLI 22 NgModule app then fails `ng test` with NG8001 on `<router-outlet>`, and every outlet fails the same way whatever the TestBed holds ([angular/angular-cli#34231](angular/angular-cli#34231), fixed by angular/angular-cli#34329 for 22.3, which is not out as a stable release yet). The NgModule spec therefore takes the outlets only where `@angular/build` 21 is installed, or, before the install, where `package.json` declares a range that admits major 21 alone. Every other case keeps the outlets out with its own note: an installed 22, an unreadable manifest, a range that spans majors, a tag, and a custom NgModule spec on 22. The note names the outlets, what the TestBed needs, and `import './app-module';` for the spec, which makes the test build compile `App` with its NgModule. |App|Outlets|Spec| |-|-|-| |CLI 21 NgModule, untouched spec|placed|outlet classes + providers| |CLI 21 NgModule, custom spec|note|unchanged| |NgModule on `@angular/build` 22 (any spec)|note, with the module import|unchanged| |Standalone|unchanged|unchanged| CI: a new `consumer-compat` row `angular-21-ngmodule` runs the onboarding path (`--preset full`) on a fresh `ng new --standalone=false` app with routing. It runs `ng add` twice (the second must change nothing), then `ng build` and `ng test`, checks both outlets in the DOM, and runs a browser smoke. No starter is expected there. The ng add bundle budget moves from 288 to 320 KB minified (gzip stays at 96 KB). The NgModule spec bodies take the catalog from 21 to 39 KB; ng add measures 308,306 B minified and 92,328 B gzip. ### Does this PR introduce a breaking change? - [ ] Yes - [x] No Migration: ### Other information **Branch protection:** the new job `angular-21-ngmodule` should be added to the required checks. Note text change: the custom-spec note now reads "is not an untouched ng new spec" instead of "is not the untouched standalone ng new spec", since the NgModule spec is supported now. Verified locally: - every `consumer-compat` row: 21.1.0 minimal; 21 full, zone, ssr; 22 full, minimal; 21 schematics `--stale-core previous --preset full`; 21 and 22 onboarding `--preset full`; the new 21 ngmodule `--preset full`; - `build:libs`, `docs:json`, `lint`, `npm test`, `test:schematics`, `test:scripts`, `build:examples`, `pack-libs --check`; - by hand on fresh apps: CLI 21 NgModule with routing on and off, zone and zoneless, green with the edited spec; CLI 22.2.3 red with any outlet; green with `@angular/build@22.3.0-next.2`, or on 22.2.3 with `import './app-module'` in the spec.
This file contains hidden or 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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
When
rootFilesoverrides are provided (such as duringunit-testruns), the initial TypeScript program is restricted to those entry points and their transitive imports. If a test imports a non-standalone@Componentdirectly without importing its declaring@NgModule, theNgModulemay be omitted from the program and leave the component without its compilation scope.Preserve the full
tsconfigroot file set asfallbackRootNamesfor application builds whenrootFilesis a subset of thetsconfigfiles. If AOT analysis detects a non-standalone component lacking an owningNgModulescope (getOwningNgModule(component) === null) and additional uncompiledtsconfigfiles exist, recreate and re-analyze the Angular program with the full root file set so allNgModuledeclarations can be discovered.