Skip to content

Migrate EOL Angular 9 stack to Angular 20 LTS toolchain#409

Open
devin-ai-integration[bot] wants to merge 2 commits into
masterfrom
devin/1782844581-angular-eol-migration
Open

Migrate EOL Angular 9 stack to Angular 20 LTS toolchain#409
devin-ai-integration[bot] wants to merge 2 commits into
masterfrom
devin/1782844581-angular-eol-migration

Conversation

@devin-ai-integration

@devin-ai-integration devin-ai-integration Bot commented Jun 30, 2026

Copy link
Copy Markdown

Summary

The entire toolchain was End-of-Life (Angular 9, TypeScript 3.7, Node 12 types, TSLint/codelyzer, Protractor, RxJS 6). This migrates the app to the current Angular 20 LTS stack and modern, supported tooling. The app builds, lints, and unit-tests clean on Node 20.

Dependency bumps (package.json)

  • @angular/* (incl. devkit/cli/compiler-cli/language-service) ~9.0.x^20.3.x
  • typescript ~3.7.5~5.9.2, rxjs ~6.5.4~7.8.0, zone.js ~0.10~0.15, tslib ^1.10^2.3, @types/node ^12^20.19
  • Removed now-unneeded deps: rxjs-compat, node-fetch (unused in src/), ts-node, @types/jasminewd2, jasmine-spec-reporter, karma-coverage-istanbul-reporter

Build system

  • Switched from the legacy webpack @angular-devkit/build-angular:browser builder to the modern esbuild-based @angular/build:application builder (angular.json rewritten). Polyfills moved into angular.json (["zone.js"]); src/polyfills.ts and src/test.ts removed (handled by the new builders). Service worker now configured via serviceWorker: "ngsw-config.json" on the production config. Output is now dist/angular-hnpwa/browser/ and still emits ngsw-worker.js.

Lint: TSLint + codelyzer → ESLint (@angular-eslint)

  • Deleted tslint.json; added eslint.config.js (flat config) and switched the lint builder to @angular-eslint/builder:lint. A few opinionated rules are intentionally disabled to preserve this app's existing architecture (prefer-standalone, prefer-inject, prefer-control-flow) and two template a11y rules (click-events-have-key-events, interactive-supports-focus) left for a separate a11y pass. All other recommended rules pass.

E2E: Protractor → Playwright

  • Removed e2e/protractor.conf.js + the Protractor spec/PO/tsconfig; added playwright.config.ts (boots npm start via webServer) and migrated the smoke test to e2e/app.spec.ts (asserts the app shell + header nav render). e2e script is now playwright test.

Unit tests / Karma

  • Updated to current Karma 6 + Jasmine 5 (karma.conf.js rewritten for the @angular/build:karma builder, dropping the old @angular-devkit/.../plugins/karma require). Added a ChromeHeadlessNoSandbox launcher for CI. Added a small comment.pipe.spec.ts so the harness exercises a real test (3 passing).

Required Angular 20 code changes

  • Standalone is the v17+ default for declarables, but this app keeps NgModules — so standalone: false was added to every @Component/@Pipe decorator.
  • RxJS 7 removed deep imports: rxjs/Observable and rxjs/Subscriptionrxjs (this is why rxjs-compat is gone).
  • Misc lint-driven fixes: typed the ga global, dropped unused imports/any, letconst, removed empty lifecycle stubs, renamed the item selector → app-item (and its template usage) to satisfy the component-selector prefix rule.

Other

  • README.md: removed the dead travis-ci.org build badge; refreshed build/lint/test/e2e instructions and Node 20 requirement. Deleted .travis.yml. Standardized on npm (removed yarn.lock, committed package-lock.json); added .nvmrc (Node 20) and ignored .angular/cache + Playwright artifacts.

Verification

  • npm run build ✅ (service worker generated)
  • npm run lint ✅ (all files pass)
  • npm test ✅ (3/3 specs, ChromeHeadless)

Notes / follow-ups

  • Builds emit non-blocking Sass deprecation warnings (@import, darken()); the SCSS theme migration is out of scope here.
  • firebase.json hosting.public (dist) already didn't match the build output path before this change; deployment config was left as-is.
  • Requires Node 20+ now — the dev environment blueprint should pin Node 20 (proposed separately).

Link to Devin session: https://app.devin.ai/sessions/a0f3b34a7f4b486c9d89067ee0649840
Requested by: @yubin-jee


Devin Review

Status Commit
⚪ Not started

Run Devin Review

Open in Devin Review (Staging)

Upgrade Angular 9 -> 20, RxJS 6 -> 7, zone.js, TypeScript 3.7 -> 5.9,
@types/node 12 -> 20; switch to the @angular/build application builder;
replace TSLint+codelyzer with ESLint (@angular-eslint) and Protractor with
Playwright; modernize Karma; remove Travis CI.

Co-Authored-By: Yubin Jee <yubinjee0310@gmail.com>
@devin-ai-integration

Copy link
Copy Markdown
Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

Co-Authored-By: Yubin Jee <yubinjee0310@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants