Modernize Angular 9 PWA to Angular 17 (standalone, ESLint, Playwright, GitHub Actions)#298
Conversation
…laywright, GitHub Actions) Co-Authored-By: Eddie Mattout <eddie.mattout@cognition.ai>
🤖 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:
|
| You can also get a job at a YC startup through <a href="https://triplebyte.com/?ref=yc_jobs">Triplebyte</a>. | ||
| </p> | ||
| } | ||
| @if (feedType !== 'new') { |
There was a problem hiding this comment.
📝 Info: Removed feedType !== 'new' guard on <ol> is a no-op change
The old template had <ol *ngIf="feedType !== 'new'" which was removed in the new template. This looks like a behavioral change, but examining the route configuration at src/app/app.routes.ts:10, the feed type for the 'newest' route is 'newest' (not 'new'), and no route ever sets feedType to 'new'. Therefore the old condition was always true and the <ol> was always rendered. Removing it doesn't change behavior. The original condition was likely a latent bug (should have been 'newest' if intended to hide the list for that feed).
Was this helpful? React with 👍 or 👎 to provide feedback.
Debug
There was a problem hiding this comment.
Fixed in 08c9c2b — removed the always-true @if (feedType !== 'new') wrapper and render the <ol> directly. I kept runtime behavior identical (the <ol> already rendered for every feed type) rather than changing it to 'newest', to avoid altering existing behavior during the modernization.
…dead condition) Co-Authored-By: Eddie Mattout <eddie.mattout@cognition.ai>
Summary
Full modernization of this Hacker News PWA from Angular 9 → Angular 17, covering all 11 requested areas: framework/TypeScript/RxJS upgrades, TSLint→ESLint, Protractor→Playwright, Travis→GitHub Actions, standalone components, new control-flow templates, PWA/service-worker consolidation, and dependency cleanup.
Approach note: A strict incremental
ng update(9→10→…→17) was not viable in this environment — Angular CLI 9 requires Node 10/12/14, but only Node 18/20/22 are available, and each major step needs a different Node + reinstalls of long-deprecated packages. Instead the workspace was rebuilt directly at Angular 17 and the (small) source ported, applying every transformation the incremental path would have produced. The end state is identical to what the incremental upgrade yields.Everything is verified locally: prod build,
ng lint, 6 unit tests (headless Chrome), and 2 Playwright e2e tests all pass.What changed
Dependencies (
package.json)@angular/*~9.0.1→^17.3.0;@angular/cli+@angular-devkit/build-angular→^17.3typescript~3.7.5→~5.4.2;rxjs~6.5.4→~7.8;zone.js~0.10→~0.14;tslib^1→^2rxjs-compat,unfetch,node-fetch,protractor,tslint,codelyzer,@types/jasminewd2@angular-eslint/*,@typescript-eslint/*,eslint,@playwright/test; bumped Karma/Jasmine to v6/v5Architecture — standalone (no NgModules)
*.module.ts(AppModule,CoreModule, feature + shared modules)main.tsnow usesbootstrapApplication(AppComponent, appConfig)app.config.tsprovides router + service worker; routing split intoapp.routes.tswith lazyloadChildrenforitem-details.routes.tsanduser.routes.tsstandalone: truewith explicitimportsRxJS 7 + native fetch
from 'rxjs',from 'rxjs/operators'); object-formsubscribe({ next, error, complete })lazyFetch<T>()inhackernews-api.service.tsuses the browser's nativefetch(nounfetch)Templates — Angular 17 control flow
*ngIf/*ngFor/*ngSwitch→@if/@for (… ; track …)role/tabindexto click targets to satisfy@angular-eslinta11y rulesTooling / CI / PWA
.eslintrc.jsonvia@angular-eslint/builder:lint);tslint.jsonremovede2e/replaced withplaywright.config.ts+e2e/app.spec.ts.travis.ymlremoved;.github/workflows/ci.ymladded (install → lint → unit tests → prod build, plus a master-only Firebase Hosting deploy job gated on aFIREBASE_SERVICE_ACCOUNTsecret)@angular/service-worker(ngsw-config.json+provideServiceWorker()), dropping the Workbox approach;manifest.json→manifest.webmanifestsrc/environments/*(replaced byisDevMode()),polyfills.ts,test.ts; updated README; switched topackage-lock.jsonNotes for reviewers
content: stringto theStorymodel sostrictTemplatesaccepts the item body binding.npm run test:ci(ChromeHeadlessCI,--no-sandbox); GitHub-hostedubuntu-latestships Chrome, so no extra setup step is needed./-division deprecation warnings are pre-existing and non-blocking.Link to Devin session: https://app.devin.ai/sessions/ff0508e294a3458e8527269660a3f20e
Requested by: @eddiemattout-cog
Devin Review
08c9c2b