chore(angular-react): Migrate Angular 9 HN PWA to React 18 + TypeScript + Vite#325
chore(angular-react): Migrate Angular 9 HN PWA to React 18 + TypeScript + Vite#325devin-ai-integration[bot] wants to merge 4 commits into
Conversation
Migrate the Angular 9 HN PWA to React 18 + TypeScript + Vite: - Services: HackerNewsAPIService -> fetch/async-await with AbortController; SettingsService -> SettingsContext (localStorage + matchMedia) - Components: Header, Footer, Settings, Feed, Item, ItemDetails, Comment, User, Loader, ErrorMessage - Routing: React Router v6 with same URLs; lazy-loaded Item/User via React.lazy/Suspense - Theming: ported SCSS (Default, Night, AMOLED) - PWA: vite-plugin-pwa + workbox; ported index.html metadata/GA/app-loader/skip-link - CI/CD: Travis + firebase.json updated to build/deploy react-app Co-Authored-By: Lukas Burger <lukaskburger@gmail.com>
…erified The React + Vite app in react-app/ has been verified running (feeds, item detail with comments, user error handling, all 3 themes, navigation). Per the playbook cleanup phase, remove Angular-specific files (src/, e2e/, angular.json, karma/tslint configs, ngsw-config.json, Angular tsconfigs, package.json, yarn.lock) and update the README to document the React/Vite build and run process. Co-Authored-By: Lukas Burger <lukaskburger@gmail.com>
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
Restore Angular DomSanitizer parity by sanitizing all dangerouslySetInnerHTML content (comments, item/poll content, user about) via a shared sanitizeHtml util. Co-Authored-By: Lukas Burger <lukaskburger@gmail.com>
There was a problem hiding this comment.
Devin Review found 1 new potential issue.
⚠️ 1 issue in files not directly in the diff
⚠️ CONTRIBUTING.md not updated after Angular-to-React migration, rendering all setup instructions non-functional (CONTRIBUTING.md:4-20)
The PR removes the root package.json, Angular CLI configuration, and all Angular source code, but does not update CONTRIBUTING.md. Steps 4–10 in CONTRIBUTING.md are now completely broken: step 4 tells contributors to install Angular CLI, step 5 says to run ng init, step 7 says npm start and localhost:4200, step 9 says npm run build at the root—none of these commands work anymore. The README was updated with the new react-app/ workflow (Vite dev server, npm run dev on port 5173, etc.), but CONTRIBUTING.md was not.
Debug
Removing <base href="/"> during migration left relative favicon/icon/splash URLs that 404 on direct navigation to sub-routes (e.g. /item/123). Convert them to root-absolute paths; avoids a <base> tag which would break the #content skip-link. Co-Authored-By: Lukas Burger <lukaskburger@gmail.com>
Summary
Migrates the Angular 9 Hacker News PWA to React 18 + TypeScript + Vite, preserving all user-facing behavior: the same URL structure, the three-theme engine, the Hacker News API data contracts, and PWA/offline support. The app now lives in
react-app/. The Angular source has been removed in this PR (cleanup phase) after the React app was verified running locally against the live API.Build, lint and type-check all pass with zero errors:
Architecture mapping (Angular → React)
HackerNewsAPIService(RxJSObservable+lazyFetch)src/services/hackernewsApi.ts—fetch/async-await+AbortController; keeps theunfetchfallback and the samehttps://node-hnapi.herokuapp.combase URL and endpointsSettingsService(DI singleton +matchMedia)src/context/SettingsContext.tsx— React Context withlocalStoragepersistence andprefers-color-schemelistenerapp.component+ router-outletsrc/App.tsx—<Routes>+ theme class + GA pageview on location changecore/header,core/footer,core/settingssrc/components/Header.tsx,Footer.tsx,Settings.tsxfeeds/feed,feeds/item(+ comment)src/components/Feed.tsx,Item.tsx,ItemDetails.tsx,Comment.tsx(recursive)item/userNgModulesReact.lazy+<Suspense>forItemDetails/Userloading/ error statessrc/components/Loader.tsx,ErrorMessage.tsxshared/models/*src/models/index.ts.scss+shared/scssthemessrc/**/*.scss(ported 1:1;:host >>>rewritten to class scoping)ngsw-config.json(Workbox)vite-plugin-pwa(generateSW) invite.config.ts— app-shell precache + runtime caching for/assets/and the HN APIindex.html(GA, theme-color, app-loader SVG, skip-link, manifest/icons)react-app/index.html(ported verbatim)Routes preserved (React Router v6)
/→ redirect/news/1;/news/:page,/newest/:page,/show/:page,/ask/:page,/jobs/:page;/item/:id;/user/:id. Pipe equivalents (timeAgo, domain, points) reimplemented as plain TS.Theming
All three themes work and persist via
localStorage: Default, Night, Black (AMOLED), plus auto-switch to Night onprefers-color-scheme: dark.PWA status
vite-plugin-pwageneratessw.js+manifest.webmanifestduring build (precaches 33 entries / ~308 KiB app shell; runtime caching mirrors the oldngsw-config.json).CI/CD
.travis.ymlnow runscd react-app && npm ci && npm run lint && npm run buildon Node 18 and deploys viafirebase deploy.firebase.jsonpublicchangeddist→react-app/dist(SPA rewrites unchanged).Verification
Ran
npm run devand exercised the app against the live API:[-]/[+]collapse toggles work./user/:idshows the error UI — note the upstreamnode-hnapi/userendpoint currently 404s for all users (includingpg), so this matches the original Angular app's behavior and is not a migration regression.Screenshots
News feed (Default theme):

Item detail with nested comments:

Night theme:

Black (AMOLED) theme:

Settings panel (theme/links/font/spacing):

Jobs feed:

Link to Devin session: https://app.devin.ai/sessions/20a1c7bc50864105bfaedd552aef24f8
Requested by: @lburgers
Devin Review
97f0e22