feat: Phase 1 - Scaffold React + TypeScript + Vite project (Angular-to-React migration)#196
Conversation
- Replace Angular dependencies with React (react, react-dom, react-router-dom) - Add Vite build tooling with @vitejs/plugin-react and vite-plugin-pwa - Create React-compatible tsconfig.json with jsx: react-jsx - Add Vite entry point (index.html) with GA snippet and PWA meta tags - Create src/main.tsx and src/App.tsx placeholder components - Set up directory structure: components, pages, hooks, context, models, utils, styles - Copy SCSS theme files (_themes, _theme_variables, _media) to src/styles/ - Create global.scss with imported themes and global styles - Copy static assets to public/ directory for Vite serving - Remove Angular-specific configs: angular.json, karma.conf.js, e2e/, etc. - Keep src/app/ as reference for subsequent migration phases Co-Authored-By: piyush@cognition.ai <piyush.b.puri@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:
|
index.html
Outdated
| <meta name="apple-mobile-web-app-capable" content="yes"> | ||
| <meta name="apple-mobile-web-app-status-bar-style" content="black"> | ||
|
|
||
| <link rel="manifest" href="/manifest.webmanifest"> |
There was a problem hiding this comment.
🟡 Duplicate manifest link tag and conflicting manifest sources from VitePWA + static file + hardcoded HTML link
The index.html has a hardcoded <link rel="manifest" href="https://github.com/manifest.webmanifest"> at line 35, while vite-plugin-pwa is configured with a manifest object in vite.config.ts:10-39 which causes it to also generate a manifest.webmanifest file and inject its own <link rel="manifest"> tag into the HTML during build. On top of that, there is a static public/manifest.webmanifest that Vite copies into dist/ verbatim.
Root Cause and Impact
Three conflicting manifest sources exist:
- Hardcoded link in
index.html:35:<link rel="manifest" href="https://github.com/manifest.webmanifest"> - VitePWA plugin in
vite.config.ts:10-39: generates a manifest file and injects its own<link>tag - Static file at
public/manifest.webmanifest: copied by Vite todist/manifest.webmanifest
The values also conflict — the static public/manifest.webmanifest has "short_name": "Angular 2 HN" while the VitePWA config has short_name: 'Hacker News'.
During production build, the output HTML will contain two <link rel="manifest"> tags (the hardcoded one plus the injected one), and the generated manifest file may collide with the static copy from public/. The result is unpredictable PWA install behavior and manifest metadata.
Fix: Remove either the hardcoded <link> from index.html (since VitePWA injects it) or the manifest config from vite.config.ts. Also remove or reconcile public/manifest.webmanifest to avoid file-level conflicts.
Prompt for agents
There are three conflicting manifest sources that need to be reconciled:
1. index.html line 35 has a hardcoded <link rel="manifest" href="https://github.com/manifest.webmanifest">.
2. vite.config.ts lines 10-39 configure vite-plugin-pwa with a manifest object, which causes the plugin to both generate a manifest.webmanifest file AND inject its own <link rel="manifest"> tag into the HTML.
3. public/manifest.webmanifest is a static file that Vite copies to dist/ as-is.
The short_name values also conflict: public/manifest.webmanifest has "Angular 2 HN" while vite.config.ts has "Hacker News".
To fix:
- Remove the hardcoded <link rel="manifest" href="https://github.com/manifest.webmanifest"> from index.html line 35, since vite-plugin-pwa injects it automatically.
- Delete public/manifest.webmanifest since vite-plugin-pwa generates the manifest from the config in vite.config.ts.
- Alternatively, if you want to use the static manifest only, remove the manifest property from the VitePWA config in vite.config.ts and keep the static file and HTML link.
Was this helpful? React with 👍 or 👎 to provide feedback.
There was a problem hiding this comment.
Good catch. Fixed in 8ff3878:
- Removed the hardcoded
<link rel="manifest">fromindex.html(vite-plugin-pwa injects it automatically) - Deleted
public/manifest.webmanifest(vite-plugin-pwa generates it from the config) - Aligned
short_nameto"Angular 2 HN"invite.config.tsto match the original manifest
- Remove hardcoded <link rel='manifest'> from index.html (vite-plugin-pwa injects it) - Delete public/manifest.webmanifest (vite-plugin-pwa generates it from config) - Align short_name to 'Angular 2 HN' in vite.config.ts to match original Co-Authored-By: piyush@cognition.ai <piyush.b.puri@gmail.com>
Summary
Phase 1 of the Angular-to-React migration for the Hacker News PWA. This PR replaces the Angular build toolchain with a Vite-based React + TypeScript setup while preserving the existing Angular source code (
src/app/) as reference for subsequent migration phases.Key changes:
@vitejs/plugin-react+vite-plugin-pwa@angular/*,rxjs,zone.js,unfetchpackages forreact,react-dom,react-router-domtsconfig.jsontargetingreact-jsx, withsrc/appexcluded to avoid Angular type errorsindex.html(repo root),src/main.tsx,src/App.tsx(placeholder)src/{components,pages,hooks,context,models,utils}/with.gitkeepfilessrc/app/shared/scss/→src/styles/, createdglobal.scsswith combined global stylessrc/assets/andsrc/favicon.ico→public/for Vite static servingvite-plugin-pwaconfig (no staticmanifest.webmanifestor hardcoded<link>tag)angular.json,karma.conf.js,e2e/,browserslist,tslint.json,ngsw-config.json,tsconfig.app.json,tsconfig.spec.json,yarn.lockyarn.lock) to npm (package-lock.json)Screenshot of running app:
Updates since last revision
<link rel="manifest">fromindex.html(vite-plugin-pwa injects it automatically), deletedpublic/manifest.webmanifest(vite-plugin-pwa generates it from config), and alignedshort_nameto"Angular 2 HN"invite.config.tsto match the original.Review & Testing Checklist for Human
tsconfig.jsonexcludessrc/app,src/main.ts,src/test.ts,src/polyfills.ts,src/environments. Verify that new React files added in future phases (e.g.src/pages/Home.tsx) are not caught by these exclusions.@importsyntax anddarken()(produces build warnings). Check that themes still work visually and don't break with future Sass updates.npm run buildand inspectdist/manifest.webmanifestto verifyvite-plugin-pwagenerates the correct manifest values (name, icons, theme color).src/app/directory is intentionally kept as reference for later phases (excluded from TypeScript but not deleted).Test Plan
Notes
src/app/Angular code is intentionally preserved as reference for future migration phases.src/assets/+public/assets/) because the oldsrc/tree is kept intact.@import,/division,darken()) are carried over from the original Angular project. These are non-blocking but should be addressed in a future cleanup PR.App.tsxis a minimal placeholder; actual component migration happens in subsequent phases.Link to Devin Session: https://app.devin.ai/sessions/4cdbb2606f7748dc8a756278bf761179
Requested by: @piyushpuri96