Skip to content

feat(custom-webpack)!: remove Karma builder and tests (Angular 22 removes Karma)#2260

Closed
just-jeb wants to merge 1 commit into
masterfrom
feat/remove-karma-v22
Closed

feat(custom-webpack)!: remove Karma builder and tests (Angular 22 removes Karma)#2260
just-jeb wants to merge 1 commit into
masterfrom
feat/remove-karma-v22

Conversation

@just-jeb
Copy link
Copy Markdown
Owner

PR Checklist

Please check if your PR fulfills the following requirements:

  • Tests for the changes have been added (for bug fixes / features)
  • Docs have been added / updated (for bug fixes / features)

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
[ ] CI related changes
[x] Documentation content changes
[x] Other... Please describe: Removal of a deprecated/unsupported builder ahead of Angular 22

What is the current behavior?

@angular-builders/custom-webpack ships a :karma builder that wraps
@angular-devkit/build-angular:karma. The package also carries Karma/Jasmine
example-app test fixtures (karma.conf.js / karma.conf.cjs, test targets in
angular.json, karma/jasmine devDependencies, puppeteer), Karma integration
tests, an e2e schema spec, and Karma documentation.

Issue Number: N/A

What is the new behavior?

The Karma builder and everything supporting it in custom-webpack are removed:

  • Deleted src/karma/ (builder + schema extension), removed the karma entry
    from builders.json, the karma scheme from src/schemes.ts, and the
    export * from './karma' from src/index.ts.
  • Deleted the e2e/custom-webpack-karma-schema.spec.ts schema test and the
    Karma documentation section from the package README.md.
  • Removed the karma-specific .gitignore line.
  • For the three custom-webpack example apps (sanity-app, sanity-app-esm,
    full-cycle-app): deleted karma.conf.*, removed the test (karma) target
    from angular.json, removed the karma/jasmine devDependencies plus
    puppeteer (these apps only used puppeteer for Karma), removed the karma
    test npm script, and removed Karma mentions from their READMEs.
  • Removed the custom-webpack: Karma ... integration tests from
    packages/custom-webpack/tests/integration.js.
  • Updated intent-layer docs (packages/custom-webpack/AGENTS.md,
    examples/AGENTS.md) to drop Karma references.

The custom-esbuild apps are untouched (they keep puppeteer and their unit-test
builder), and the CI PUPPETEER_SKIP_DOWNLOAD env / runner pinning from #2259 is
left as-is.

Verification: yarn install --immutable passes, yarn workspace @angular-builders/custom-webpack build succeeds (tsc + merge-schemes produce
only browser/server/dev-server/extract-i18n schemas, no karma), and
node scripts/discover-tests.js lists no custom-webpack: Karma tests.

Does this PR introduce a breaking change?

[x] Yes
[ ] No

The @angular-builders/custom-webpack:karma builder is removed. Angular 22 no
longer ships a Karma builder (@angular-devkit/build-angular:karma is gone), so
the wrapper cannot continue to exist. Users on a test target using
@angular-builders/custom-webpack:karma must migrate to a supported test runner
(Vitest / Web Test Runner, or @angular-builders/jest).

Other information

This is a v22-targeted breaking change to be merged only once Angular 22 is
released. Karma is removed upstream in Angular 22. A Vitest / Web Test Runner
replacement is tracked in #1928.

…oves Karma)

Angular 22 removes the Karma test builder entirely. The custom-webpack
`:karma` builder wraps `@angular-devkit/build-angular:karma`, which will
not exist in v22, so it is removed here along with its example-app test
fixtures, integration tests, and documentation.

BREAKING CHANGE: The `@angular-builders/custom-webpack:karma` builder has
been removed. Angular 22 no longer ships a Karma builder. Migrate your
`ng test` target to a supported test runner (e.g. Vitest / Web Test Runner
or `@angular-builders/jest`).
just-jeb added a commit that referenced this pull request Jun 2, 2026
- 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
@just-jeb
Copy link
Copy Markdown
Owner Author

just-jeb commented Jun 2, 2026

Holding this PR — Angular 22 does not remove Karma

Re-checked against the actual Angular 22.0.0-rc.3 install and Angular's published roadmap, and the premise behind this PR ("Angular 22 removes Karma") doesn't hold:

  • The karma builder still ships in both @angular/build and @angular-devkit/build-angular in v22 — not flagged deprecated/hidden in builders.json. ng new flips the default runner to Vitest but still offers --test-runner karma; the Vitest unit-test builder is still [EXPERIMENTAL].
  • ng update to v22 keeps existing Karma users on Karma (migrates the test builder to @angular/build:karma; does not delete karma.conf/test.ts or switch to Vitest). Vitest is opt-in via ng generate @angular/core:karma-to-vitest.
  • Karma is deprecated, with security-only support continuing ~12 months after Vitest is marked stable (that clock hasn't started — still experimental). Angular's deprecation policy is a minimum of two majors, so full removal is ≈v24+, not v22.
  • Our own v22 matrix confirms it: custom-webpack Karma+Chrome integration tests pass green on 22.0.0-rc.2.

Removing @angular-builders/custom-webpack's :karma builder in v22 would therefore strand Karma users that Angular itself still supports — a gratuitous breaking change, not a forced consequence.

Action: converting to draft and holding until the major where Angular actually removes Karma (re-evaluate at that cut). The v22 schematics design has been amended accordingly (custom-webpack ships ng-add only, no Karma-removal @22 migration; the v22 breaking set is now #2191 + #2212).

Sources: angular.dev/guide/testing/migrating-to-vitest · angular.dev/reference/releases · angular-cli commit 8654b3f.

@just-jeb just-jeb marked this pull request as draft June 2, 2026 12:13
just-jeb added a commit that referenced this pull request Jun 3, 2026
- 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
@just-jeb
Copy link
Copy Markdown
Owner Author

just-jeb commented Jun 4, 2026

Closing — based on a false premise. Angular 22 deprecates Karma, it does not remove it. ng new defaults to Vitest, but --test-runner karma still works and @angular/build:unit-test with runner: "karma" (and @angular-devkit/build-angular:karma) still ship. ng update @angular/core to v22 keeps existing Karma users on Karma. Full removal is a future major (~v24+, per Angular's 2-major deprecation policy). Will reopen against the appropriate major when Angular actually removes Karma.

@just-jeb just-jeb closed this Jun 4, 2026
just-jeb added a commit that referenced this pull request Jun 4, 2026
…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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant