Skip to content

build: require Angular 21.2 and compile with its toolchain - #3763

Open
armando-navarro wants to merge 2 commits into
angular:mainfrom
armando-navarro:angular-minimum-21.2
Open

armando-navarro wants to merge 2 commits into
angular:mainfrom
armando-navarro:angular-minimum-21.2

Conversation

@armando-navarro

Copy link
Copy Markdown
Collaborator

Checklist

  • Issue number for this PR: none, release coordination for the 21.0.0-rc.1 cut
  • Docs included?: no, dependency manifests and the build script only
  • Test units included?: no new specs. The existing suite passes (331 specs, 0 failures) and the build's own schematics-load check covers the new build step.
  • In a clean directory, yarn install, yarn test run successfully?: yes

Description

Raises the minimum supported Angular to 21.2, the final 21.x minor line. Angular 21 is in long-term support, which receives only critical fixes and security patches, so ^21.2.0 admits every 21.x release still to come. The raise is release coordination for the TransferState work (#3757), whose signal-based reading functions build on resourceFromSnapshots, absent from @angular/core until 21.2.

Changes

  • The four Angular peer entries in src/package.json move to ^21.2.0.
  • The repo's own Angular build packages move to ^21.2.0, @angular-devkit/architect moves to ~0.2102.0 because the 21.2 CLI needs a devkit version the old ~0.2100.0 range rejects (lockfile regenerated).
    • The two @angular-eslint entries stay at ^21.0.0, since that project's 21.x minors do not track Angular's.
  • Deletes the "type": "module" field that ng-packagr 21.2 adds to package.json (a default introduced in ng-packagr#3263).
    • Otherwise, Node reads the CommonJS schematics bundles as ES modules, breaking ng add and ng deploy.
    • The schematics-load check runs after the deletion so a regression fails the build.
    • This maintains the manifest's status quo that every published release has carried.

Verification

  • Full build passes, and the built package.json carries no type field.
  • The regenerated entry points are byte-identical under the 21.2 compiler, so the published surface does not change.
  • 331 specs, 0 failures, lint clean.
  • The 21.2 tools require Node ^20.19.0 || ^22.12.0 || >=24.0.0, which CI's Node 20, 22 and 24 matrix satisfies.
  • The sample app already installs @angular/core 21.2.18, so it needs no change to satisfy the new peer range.

Angular 21 is in long-term support.
… module type field

ng-packagr 21.2 adds "type": "module" to the generated
package.json, which breaks the CommonJS schematics bundles at require
time. The build now deletes the field and its schematics-load check
runs after the deletion.
@armando-navarro armando-navarro added bump: patch comp: build/pipeline Build, bundling, packaging, release pipeline. type: chore Maintenance with no user-facing behavior change. labels Sep 9, 2026

@tyler-reitz tyler-reitz left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Built both heads and ran the regression by hand. The change does what the body says. One thing to fix before merge, the rest is comment-level.

Fix first: docs/version-21-upgrade.md:82 still reads "AngularFire 21 peers @angular/* ^21.0.0", so it ships contradicting the new src/package.json, in the guide specifically about this constraint.

The load guard is Node-dependent. Re-adding "type": "module" to the built manifest and requiring the six entry points:

Node Result
18.20.8 throws ERR_REQUIRE_ESM
20.20.2 / 22.15.0 / 24.14.1 throws module is not defined in ES module scope
26.7.0 no throw; all six export {}

It holds on CI, but engines >=24.0.0 admits 26, where loadCompiledSchematics passes silently because it only catches throws. Asserting the loaded module has exports closes that.

Concurrent writers on the built manifest. buildLibrary runs compileSchematics() (now calling dropEsModulePackageType) and replacePackageCoreVersion() in one Promise.all (tools/build.ts:454-460), and both read-modify-write dist/packages-dist/package.json. The ordering holds today only because compileSchematics is slower, and both inversions fail silently: the type field survives, or ANGULARFIRE2_VERSION ships as the version. Awaiting replacePackageCoreVersion() before the Promise.all costs nothing. Inferred from the code, not reproduced.

"Byte-identical" overstates it, though the conclusion holds. Diffing clean builds of c8aebe1 and 5b3112a: 67 files differ, all either the partial-compile version: stamp (21.0.0 to 21.2.22) or .d.ts import reordering. Public surface unchanged.

Nit: @schematics/angular stays at ^21.0.0 while its siblings move. It resolves to 21.2.23 so it's harmless, just unexplained next to the @angular-eslint note.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bump: patch comp: build/pipeline Build, bundling, packaging, release pipeline. type: chore Maintenance with no user-facing behavior change.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants