Skip to content

feature: Angular 9 → React + TypeScript PWA migration (react-app/: Vite, React Router, TanStack Query, vite-plugin-pwa, Firebase, GitHub Actions) - #878

Open
devin-ai-integration[bot] wants to merge 33 commits into
masterfrom
devin/1791469878-react-phase0-foundation
Open

devin-ai-integration[bot] wants to merge 33 commits into
masterfrom
devin/1791469878-react-phase0-foundation

Conversation

@devin-ai-integration

@devin-ai-integration devin-ai-integration Bot commented Oct 8, 2026 •

Copy link
Copy Markdown

Summary

This PR is the complete Angular 9 → React + TypeScript migration. It adds a standalone Vite PWA in react-app/ and leaves the Angular app in src/ untouched. Phase 0 (foundation) landed here first. The five parallel workstreams were then merged into this branch:

Workstream PR What
A – shell + theming #879 core/Header, Footer, Settings; Default / Night / AMOLED themes, persisted to the same localStorage keys as Angular
B – feeds #880 feeds/Feed + Item: all 5 feeds, pagination, title-size/spacing settings
C – item + comments #882 item-details/ItemDetails + recursive Comment (collapse keeps the DOM via hidden), polls
D – user #881 user/User (HNPWA API, because node-hnapi /user returns 404)
E – PWA / deploy #883 vite-plugin-pwa (generateSW, NetworkFirst API caches, SPA navigateFallback), a cleanup worker at the old /ngsw-worker.js URL that retires the Angular SW, firebase.json → react-app/dist, .travis.yml → .github/workflows/react-app.yml

Stack: Vite 7, React 19, React Router 7, TanStack Query 5, Sass, Vitest + Testing Library, Playwright, ESLint 9, and Prettier (settings copied from the root package.json).

Phase 0 foundation:

  • shared/models/*: the Angular model classes become interfaces with the same fields.
  • HackerNewsAPIService → shared/services/hackernews-api.ts: Promise + AbortSignal, wrapped by the useFeed / useItem / useUser hooks. Poll options load with Promise.allSettled, so one failed option no longer breaks the whole item.
  • SettingsService → SettingsProvider + useSettings().
  • The comment pipe → formatCommentCount.
  • sanitizeHtml: an allowlist sanitizer, because React doesn't sanitize innerHTML the way Angular did.
  • app.routes.ts → router/routes.tsx:
    /                                   -> /news/1
    /{news,newest,show,ask,jobs}/:page  handle: { feedType }
    /item/:id, /user/:id                lazy()
    

Deliberately dropped: the Google Analytics UA snippet. Universal Analytics was shut down in 2023.

Tests (Phase 2)

  • Unit tests: npm test runs 126 Vitest + Testing Library tests in 14 files. The Angular app had no Karma specs to port; the Protractor spec only checked the page title and console errors.
  • e2e: npm run e2e runs 12 Playwright tests against the production build. 36/36 passed with --repeat-each=3.
    • e2e/app.spec.ts (mocked API) covers: the / redirect, all feed nav links, pagination numbering from 31, item page sanitizing and nested comments, a user profile and the unknown-user error, theme persistence across reloads, and no console errors (the check ported from the Protractor spec).
    • e2e/offline.spec.ts covers: first visit then offline reload, offline deep links, and the Angular SW → React SW upgrade.
  • CI: the GitHub Actions check and e2e jobs are green on this PR. deploy runs only on pushes to master when a FIREBASE_SERVICE_ACCOUNT or FIREBASE_TOKEN secret exists.

Lighthouse (Lighthouse 12, vite preview, /news/1, live API, integrated build):

Perf A11y Best practices SEO FCP LCP TBT CLS
React, mobile 100 96 100 100 0.8 s 0.9 s 20 ms 0
React, desktop 100 96 100 100 0.4 s 0.4 s 0 ms 0
Angular ng build --prod, mobile (from #883) 97–98 100 100 92 ~1.5 s ~1.5 s 155–200 ms 0

The accessibility score of 96 comes from link-in-text-block: the mobile .comment-number link is red on grey with no underline. The markup and colours are copied unchanged from the Angular item.component. I left it as is to keep visual parity.

Link to Devin session: https://devin-gtm.devinenterprise.com/sessions/7cf5168b5db44e91b8292c4e209d4584
Open in Devin Desktop: https://devin-gtm.devinenterprise.com/desktop/session/7cf5168b5db44e91b8292c4e209d4584?variant=devin
Requested by: @ishita-cog


Note

Devin errored when opening this Pull Request as ishita-cog.
As a fallback, Devin opened this PR as itself.


Devin Review

Status Commit
⚪ Not started —

Run Devin Review

Devin Review (Staging)


Devin Review

…ery hooks, settings, router, utils)

Co-Authored-By: Ishita Gupta <ishita.gupta@cognition.ai>
@devin-ai-integration

Copy link
Copy Markdown
Author

I'll fix CI failures and address comments from users with write access. I'll skip comments containing "(aside)".

  • Disable automatic comment, CI, and merge conflict monitoring

devin-ai-integration[bot]

This comment was marked as resolved.

devin-ai-integration Bot and others added 27 commits October 8, 2026 14:36
…ngs, time_ago type, mstile path)

Co-Authored-By: Ishita Gupta <ishita.gupta@cognition.ai>
Co-Authored-By: Ishita Gupta <ishita.gupta@cognition.ai>
Co-Authored-By: Ishita Gupta <ishita.gupta@cognition.ai>
Co-Authored-By: Ishita Gupta <ishita.gupta@cognition.ai>
…undation' into devin/1791470119-react-user-profile
…o React

Co-Authored-By: Ishita Gupta <ishita.gupta@cognition.ai>
Co-Authored-By: Ishita Gupta <ishita.gupta@cognition.ai>
…I for the React app

Co-Authored-By: Ishita Gupta <ishita.gupta@cognition.ai>
…undation' into devin/1791470086-react-pwa-build-deploy
…and comment link styles

Co-Authored-By: Ishita Gupta <ishita.gupta@cognition.ai>
Co-Authored-By: Ishita Gupta <ishita.gupta@cognition.ai>
…undation' into devin/1791470088-react-item-details
…undation' into devin/1791470119-react-user-profile
Co-Authored-By: Ishita Gupta <ishita.gupta@cognition.ai>
…undation' into devin/1791470086-react-pwa-build-deploy
Co-Authored-By: Ishita Gupta <ishita.gupta@cognition.ai>
… error for non-numeric item ids

Co-Authored-By: Ishita Gupta <ishita.gupta@cognition.ai>
…hange, scope popup styles to #popup1

Co-Authored-By: Ishita Gupta <ishita.gupta@cognition.ai>
Co-Authored-By: Ishita Gupta <ishita.gupta@cognition.ai>

# Conflicts:
#	react-app/src/router/routes.test.tsx
…ook control

Co-Authored-By: Ishita Gupta <ishita.gupta@cognition.ai>
Co-Authored-By: Ishita Gupta <ishita.gupta@cognition.ai>
…undation' into devin/1791470086-react-pwa-build-deploy
…rs from cache

Co-Authored-By: Ishita Gupta <ishita.gupta@cognition.ai>
devin-ai-integration Bot and others added 4 commits October 8, 2026 14:57
… first-visit cache warm-up

Co-Authored-By: Ishita Gupta <ishita.gupta@cognition.ai>
…ettings (ported Protractor coverage)

Co-Authored-By: Ishita Gupta <ishita.gupta@cognition.ai>
@devin-ai-integration devin-ai-integration Bot changed the title feature: React migration Phase 0 foundation (react-app/ scaffold, models, API hooks, settings, router) feature: Angular 9 → React + TypeScript PWA migration (react-app/: Vite, React Router, TanStack Query, vite-plugin-pwa, Firebase, GitHub Actions) Oct 8, 2026
devin-ai-integration[bot]

This comment was marked as resolved.

Co-Authored-By: Ishita Gupta <ishita.gupta@cognition.ai>
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