feat!: Angular 22 support (release/v22)#2284
Open
just-jeb wants to merge 8 commits into
Open
Conversation
* chore(deps): bump Angular builder ranges to 22.0.0-rc.2 Extend update-package.js/update-example.js to accept explicit version strings and dist-tags (required for RC prework), and bump all @angular-builders/* Angular dependency ranges to 22.0.0-rc.2. * chore(deps): upgrade example apps to Angular 22.0.0-rc.2 and fix TS6 build breakage - Bump example apps to Angular 22.0.0-rc.2 and TypeScript 6.0.3. - Add explicit rootDir to package tsconfigs (TS6 TS5011 now requires it when emitting with outDir). - Add @types/node + types:[node] to standalone packages bazel/timestamp (TS6 no longer auto-includes node types without a transitive trigger). - jest: move types into compilerOptions and pin to @types/jest so the ambient jest global resolves under TS6 (the bare 'jest' entry now resolves to the runtime jest package, which lacks the global); exclude spec files from the lib build so they stop leaking into dist. * fix(examples): resolve TS6 breakage in example apps for Angular 22 - Add ignoreDeprecations: "6.0" to app tsconfigs using deprecated options (baseUrl, downlevelIteration) that TS6 now errors on. - Add rootDir to Cypress e2e tsconfigs so ts-loader stops failing with TS5011 under TS6. - full-cycle-app webpack configs: switch html-webpack-plugin to a default import (TS6 rejects constructing a namespace import) and guard the optional cfg.plugins array.
…webpack (#2267) * docs(schematics): add v22 builder ng-add + ng-update design spec * docs(schematics): cover v22-held breaking PRs (#2191/#2212) and MIGRATION.MD pairing * docs(schematics): add Plan 0 — common/schematics core + packaging * docs(schematics): add Plans 01-03 — jest, custom-esbuild, custom-webpack Builder implementation plans referencing Plan 0's locked common/schematics API contract. Reviewed for consistency: all import the shared helpers, none redefine them, no raw fs (tree-based edits only). * docs(schematics): add v17→v22 migration coverage caveat + 2c/2d execution checklist - jest plan: document the stepwise-through-v21 skip + single-step old→22 flow and RC-time multi-major ng update validation - new 2c/2d checklist: holds rebase, MIGRATION.MD pairing, RC validations, and the two e2e testing gaps (ng add integration, jest @21 post-migration smoke) * docs(schematics): amend design for Karma roadmap (not removed in v22) - spec §12: Karma deprecated-not-removed in v22; drop custom-webpack @22 migration + hold #2260; add jest Vitest→Jest path; add custom-esbuild webpack-build guard; fix e2e fixtures - spec §4.3/§5: custom-webpack ng-add-only; v22 breaking set = #2191+#2212 - 2c/2d checklist: #2260 off the v22 holds, Karma fixture via ng new, e2e cases * docs(schematics): apply §12 amendments to builder plans - jest (Plan 01): add Vitest→Jest ng-add path (Task 4b), keep Karma→Jest - custom-esbuild (Plan 02): add webpack-build guard + --from-webpack (Task 3b) - custom-webpack (Plan 03): drop @22 Karma-removal migration, ng-add only Reviewed: no shared-helper redefinition, no raw fs in schematic code, webpack @22 migration fully removed (remaining refs assert its absence). * docs(schematics): add Plan 04 — schematics integration/e2e tests ng add e2e per builder (jest Karma→Jest + Vitest→Jest, esbuild build + webpack guard, webpack scaffold) via npm pack→ng add tarball into the existing integration matrix; jest @21 post-migration build smoke; RC multi-major ng update validation. * build(common): add schematics subpath packaging (tsconfig + exports + copy) * feat(common): add schematics version helpers * feat(common): add SchematicTestHarness for schematics unit tests Also stubs ESM-only `ora` (via @angular-devkit/schematics task executor chain) with a moduleNameMapper in jest-ut.config.js, and resolves @schematics/angular/collection.json via package.json to bypass the exports map (required in Node 22+). * feat(common): add workspace detection helpers for schematics * feat(common): add composable schematics rule factories * feat(common): export schematics core via ./schematics subpath * build(jest): add schematics packaging (tsconfig + fields + copy) * feat(jest): add ng-add collection + schema (project flag only) * feat(jest): ng-add adds jest stack and rewrites test target * feat(jest): declare ng-update migrations manifest (v21, v22) * feat(jest): v21 migration bumps deps and applies Node16 tsconfig * feat(jest): v22 advisory migration (isolatedModules, coverage path) * build(custom-esbuild): add schematics packaging (tsconfig + ng-add fields + copy) * feat(custom-esbuild): add ng-add collection + schema manifests * feat(custom-esbuild): ng-add rewrites build/serve preserving options * feat(custom-esbuild): ng-add guards webpack builds, adds --from-webpack (spec §12.3) * feat(custom-esbuild): ng-add auto-rewrites Vitest test target with buildTarget * feat(custom-esbuild): ng-add leaves Karma/Jest tests, logs unit-test advisory * feat(custom-esbuild): ng-add --unit-test force-creates Vitest target * test(custom-esbuild): assert ng-add idempotency * build(custom-esbuild): verify schematics build * build(custom-webpack): add schematics packaging (tsconfig + ng-add field) * feat(custom-webpack): add ng-add schema (project flag, no prompts) * feat(custom-webpack): add starter webpack.config scaffold template * feat(custom-webpack): add ng-add (build/serve rewrite + config scaffold) * test(custom-webpack): verify schematics build + no-migrations invariant * fix(jest): add WorkspaceDefinition casts and JsonValue fixes for schematics tsc * test(schematics): add local-only ng add e2e harness helpers * build(schematics): use Node16 module resolution for schematics build The schematics tsconfig used module:commonjs + moduleResolution:node (node10). node10 is deprecated in TypeScript 6 (Angular 22) AND ignores package exports maps — the latter is why each package's schematics tsconfig carried a 'paths' override just to resolve @angular-builders/common/schematics. Align with the main builder tsconfig (module/moduleResolution Node16): all packages are CJS (no type:module), so Node16 still emits CommonJS as schematics require, while honoring exports maps. This drops the paths workaround in all three packages and needs no deprecation suppression. Add types:[node] since TS6 no longer auto-includes node ambients. * test(schematics): generate ng-add e2e fixtures inline, default to no-install collection run ng add e2e now generates the target app inline with the workspace CLI (ng new) instead of committing a fresh-scaffold fixture — self-describing and immune to fixture drift across Angular majors. Default ng add path resolves the collection from the workspace-linked package with --skip-install (the schematic under test runs fully; no package-manager step, so it can't mutate the symlinked node_modules). npm-pack tarball path kept behind useTarball:true for a future isolated-install CI. * fix(schematics): handle Angular 22 unified :unit-test runner model Angular 22 expresses Karma and Vitest as the same @angular/build:unit-test builder, distinguished by an options.runner ('karma' | 'vitest') field, rather than a dedicated :karma builder (which still exists for webpack projects). The schematics, written for the v21 model, broke on v22: - detectTestBuilder classified every :unit-test target as Vitest, so Karma on a default (esbuild) v22 app was invisible. Now it reads options.runner for :unit-test builders and keeps the :karma suffix branch for webpack projects. - jest ng-add merged {zoneless} onto the previous target's options, leaving the foreign builder's runner/buildTarget behind; the Jest builder then forwarded --runner to the Jest CLI ('Runner is not a constructor'). setBuilderForTarget gains an opt-in replaceOptions (default still merges, preserving other callers); jest ng-add uses it to start from a clean Jest option set. Surfaced by the Plan 04 ng-add e2e (ng new --test-runner karma -> ng add -> ng test). * test(jest): add Karma->Jest ng add e2e (inline fixture, real ng test) * test(jest): add Vitest->Jest ng add e2e (ng build + ng test green) * test(custom-esbuild): add build/serve rewrite ng add e2e * test(custom-esbuild): add webpack-build guard ng add e2e * test(custom-webpack): add build/serve rewrite + scaffold ng add e2e * test(jest): add @21 migration post-build smoke; fix testPathPatterns string->array The @21 migration renamed testPathPattern -> testPathPatterns but carried the value over verbatim. Jest 30's testPathPatterns is a string array, so a migrated config failed builder schema validation ('testPathPatterns must be array') at ng test. Wrap a carried-over string in an array. Surfaced by the new ng update --migrate-only post-build smoke (Plan 04 Task 6), which seeds a pre-21 config on an inline-generated app, runs the migration, then ng build + ng test. * docs(runbook): record RC-validated multi-major ng update window * test(schematics): neutralise package manager during ng add via PATH shim The ng add collection run can't use --skip-install (ng add forwards it to the schematic, whose schema rejects unknown options). Instead prepend a no-op npm/yarn/pnpm shim to PATH for the ng add spawn so the schematic's NodePackageInstallTask runs harmlessly — it cannot write through the workdir's node_modules symlink into the workspace. Every tree transform still happens; ng build/test afterwards resolve from the workspace-linked modules. * fix(custom-webpack): declare @angular-devkit/schematics and @schematics/angular deps custom-webpack's ng-add imports from both packages but didn't declare them, relying on them being present transitively via the user's @angular/cli install. Declare them explicitly (matching jest and custom-esbuild) so ng add resolves regardless of hoisting.
…ixes #1899) (#2191) * fix(jest): default isolatedModules to true for faster compilation (fixes #1899) Angular 19 introduced signals, new control flow syntax, and standalone-by-default components. These produce significantly more complex TypeScript that causes the ts-jest language service (used when isolatedModules: false) to build a full cross-file Program per test file, resulting in severe slowdowns (reports of 2 min → 15 min test runs). Root cause: when isolatedModules is false (previously the implicit default), ts-jest instantiates a TypeScript LanguageService and rebuilds a full Program for each file. Angular 19+'s richer type surface makes this path prohibitively slow. Fix: set isolatedModules: true in the builder's default transformer options. This switches ts-jest to its fast per-file transpile path, matching the recommendation from jest-preset-angular's own example apps since v14.4.0. Cross-file type checking is better served by tsc --noEmit or ng build. Users who need the previous behaviour can opt out in their jest.config.ts: transform: { '^.+\.(ts|js|mjs|html|svg)$': ['jest-preset-angular', { isolatedModules: false }] } BREAKING CHANGE: isolatedModules now defaults to true. This disables cross-file TypeScript type checking during jest runs. Targeted for the next major version. * test(jest): replace config-shape assertions with behavioral integration test Remove isolatedModules:true assertions from the unit spec — they tested implementation details (object shape), not user-visible behavior. Replace with targeted assertions on tsconfig path resolution, which is the actual behavioral contract of the resolver. Add isolated-modules-default integration test entry that proves Angular component tests still pass end-to-end with isolatedModules:true active, providing the behavioral regression guard for #1899. --------- Co-authored-by: Houston (Jeb's AI) <houston@base44.com>
…aces (fixes #1009) (#2212) * fix(jest): scope coverage output per-project in multi-project workspaces (fixes #1009) * fix(jest): scope coverageDirectory per project to prevent output collisions (#1009) When running ng test in a multi-project Angular workspace, each project's coverage output was written to the same directory (e.g. root ./coverage/), causing each successive run to overwrite the previous project's coverage report. Fix: set coverageDirectory in DefaultConfigResolver.resolveForProject() to <projectRoot>/coverage so each Angular project's coverage lands in its own isolated output directory. This is a project-level default that can still be overridden per-project via the jest.config.js customization mechanism. Also removes erroneous debug console.log statements from jest-configuration-builder.ts and fixes the scopeOutputDirectoriesForProjects approach, which incorrectly mutated the Jest 'projects' array (breaking --find-related-tests and project path resolution). Adds: unit test for coverageDirectory scoping, integration test validate-coverage.js * test(jest): remove impl-detail coverageDirectory spec, keep behavioral integration test The unit test asserting config.coverageDirectory field value is an implementation detail check. The behavioral proof — that coverage files actually land under projects/<name>/coverage/ on disk — is covered by the integration test in validate-coverage.js. Remove the unit test to avoid false confidence from a config-shape assertion. --------- Co-authored-by: Houston <houston@superagent.local> Co-authored-by: Houston <houston@base44.com>
Sync the v21 maintenance line (renovate bumps, the #1859 --findRelatedTests positional-args fix (#2237), and other v21 fixes) into the Angular 22 branch. Conflicts: - examples/*/package.json: kept v22 Angular versions (22.0.0-rc.2); master's incidental devDep bumps auto-merged outside the conflict hunks. - yarn.lock: kept v22 lockfile, reconciled to merged manifests. - package.json: bumped root @angular/build ^21 -> ^22.0.0-rc.2 (added on master via #2239) so merge-schemes.ts resolves Angular 22's base schema.
myabc
added a commit
to opf/openproject
that referenced
this pull request
Jun 7, 2026
Necessary until a compatible version of @angular-builders/custom-esbuild is released. See just-jeb/angular-builders#2284
myabc
added a commit
to opf/openproject
that referenced
this pull request
Jun 7, 2026
Necessary until a compatible version of @angular-builders/custom-esbuild is released. See just-jeb/angular-builders#2284
myabc
added a commit
to opf/openproject
that referenced
this pull request
Jun 7, 2026
Necessary until a compatible version of @angular-builders/custom-esbuild is released. See just-jeb/angular-builders#2284
3 tasks
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.
PR Checklist
PR Type
What is the current behavior?
Builders track Angular 21 (
@angular/build ^21). There is no published support for Angular 22, and installation/upgrade for the Jest builder is still a manual process.This is the long-lived Angular 22 release branch. It branched off
masteratbc2e3819and carries the v22 upgrade work.What is the new behavior?
Upgrades all builders + example apps to Angular 22 (currently
22.0.0-rc.2) and lands the supporting tooling/migrations.Commits on this branch (vs merge-base
bc2e3819):ng add/ng updateschematics for jest, custom-esbuild, custom-webpack (feat: ng add / ng update schematics for jest, custom-esbuild, custom-webpack #2267) — automates Jest installation/migration (closes Use schematics for installation steps #22)isolatedModulestotruefor faster compilation (fix(jest)!: default isolatedModules to true for faster compilation (fixes #1899) #2191) — addresses the Angular 19 Jest perf regression (Performance regression on jest tests after upgrading to Angular 19 #1899)Closes #1899, #1009, #22 once released under the v22 line.
Does this PR introduce a breaking change?
Major version bump aligned with Angular 22. Per project invariant, a v22 builder requires Angular CLI 22. Additional breaking changes within the line:
isolatedModulesnow defaults totrue(Jest) — faster compilation; some projects relying on full-program type-checking during transform may need to adjust.Migration path: see the v21 → v22 migration section added in #2273 and the new upgrade runbook.
Other information