--- id: PROJ-79 title: Frontend-Dependency-Major-Upgrades (eslint, lucide-react, tailwindcss+tailwind-merge, typescript, @types/node) status: In Progress created: 2026-08-05 --- ## Problem `npm outdated` zeigt mehrere Major-Version-Sprünge im Frontend, die nicht blind gezogen werden sollten (Build-/Runtime-Bruchrisiko): | Paket | Aktuell | Ziel | Risiko | |---|---|---|---| | `eslint` | 9.39.2 | 10.8.0 | Config-Format | | `typescript` | 5.9.3 | 7.0.2 | 2 Majors auf einmal | | `tailwindcss` | 3.4.19 | 4.3.3 | Komplett neue Config-Architektur | | `lucide-react` | 0.562.0 | 1.28.0 | Icon-API-Änderungen | | `tailwind-merge` | 2.6.0 | 3.6.0 | **Hart an tailwindcss v4 gekoppelt** | | `@types/node` | 20.19.28 | 26.1.2 | Typen sollten zur echten Node-Version auf 131/132 passen | Wichtiger Befund während der Umsetzung: `tailwind-merge` v3 setzt laut offizieller README **Tailwind CSS v4** voraus ("if you use Tailwind v3, use tailwind-merge v2.6.0"). Ein isoliertes Upgrade von `tailwind-merge` allein wäre eine offiziell unsupported Kombination — heute laut Messung (283.556 paarweise Klassen-Merges aus dem echten Codebestand verglichen, 0 Abweichungen) verhaltensneutral, aber `*-opacity-*`-Klassen (z.B. `bg-opacity-50`) würden künftig **lautlos** falsch gemerged statt einen Build-Fehler zu werfen. ## Lösung (Vorschlag, priorisierte Reihenfolge) 1. **`lucide-react`** 0.562.0 → 1.28.0 — unabhängig, `grep -rn "from \"lucide-react\"" src/` für Impact-Fläche, danach Upgrade + `tsc --noEmit` (fängt umbenannte Icons als Compile-Fehler ab). 2. **`eslint`** 9 → 10 + `eslint-config-next` (aktuell 16.1.1) nachziehen, Flat-Config-Breaking-Changes prüfen, `npm run lint` danach. 3. **`@types/node`** 20 → 26 — vorher `node -v` auf 131 und 132 prüfen, Typen dürfen nicht vor der tatsächlichen Node-Laufzeit-Version liegen. 4. **`tailwindcss` v3→v4 + `tailwind-merge` v2→v3 zusammen** (gekoppeltes Paar, nicht einzeln): - `npx @tailwindcss/upgrade` (offizielles Migrationstool) - `tailwind-merge@3` im selben Schritt - shadcn/ui-Komponenten-Kompatibilität mit Tailwind 4 vorab prüfen - Lint-Regel gegen `*-opacity-*`-Klassen ergänzen (bg-/text-/border-/ring-/divide-/placeholder-opacity) — Absicherung gegen stummen Styling-Bruch, da diese Klassen in v4 vom Merge verschluckt werden ohne Fehler - Voller visueller Regressionstest (größter Einzelschritt im gesamten Upgrade-Batch) 5. **`typescript`** 5 → 6 → 7 — stufenweise, nicht direkt springen, nach jedem Schritt `tsc --noEmit` komplett grün vor dem nächsten. Jeder Schritt: eigener Commit, erst auf 132 build+visuell testen, dann 131. ## Implementation Notes - 2026-08-05: `tailwind-merge`-Einzelupgrade gestoppt nach Entdeckung der v4-Kopplung (siehe Problem-Abschnitt). Kein Code geändert, `git status` war danach sauber. Reihenfolge oben entsprechend revidiert — Punkt 4 bündelt beide Pakete statt sie getrennt zu behandeln. ### lucide-react Upgrade (Punkt 1) — 2026-08-05 - `lucide-react` 0.562.0 → **1.28.0** (`npm install lucide-react@^1`). Geändert wurden nur `package.json` / `package-lock.json` — **kein Anwendungscode musste angepasst werden.** - Impact-Fläche: 19 Dateien unter `src/`, alle Imports einzeilig, insgesamt 20 verschiedene Icons: `Bookmark`, `BookmarkPlus`, `Check`, `ChevronDown`, `ChevronLeft`, `ChevronRight`, `ChevronUp`, `Circle`, `FileText`, `Info`, `Lock`, `MailPlus`, `Moon`, `MoreHorizontal`, `PanelLeft`, `Search`, `Server`, `Sun`, `Trash2`, `X`. - **Keine Icon-Umbenennungen nötig:** alle 20 Namen existieren unverändert in den v1-Typdeklarationen (`node_modules/lucide-react/dist/lucide-react.d.ts`) — es handelt sich durchweg um kanonische Namen, keine veralteten Aliase, die beim 0.x→1.x-Sprung entfallen wären. - Verifikation: `npx tsc --noEmit` → **0 Fehler**; `npm run build` → **erfolgreich**, alle 14 Routen generiert. - Kein Live-Browser-Test durchgeführt (laut Spec-Auftrag nicht nötig, da fehlende Icon-Exporte vollständig als Compile-Fehler auftreten würden). - Offen: Verifikation auf 132, danach 131-Deploy. ### npm audit fix + Browserslist-Refresh — 2026-08-05 Anlass: beim 131-Deploy meldete `npm ci` 26 Vulnerabilities (1 low, 6 moderate, 19 high) sowie eine 8 Monate alte `caniuse-lite`-Datenbank (Browserslist). Lokal (nach dem lucide-react-Upgrade) zeigte `npm audit` nur 6 Vulnerabilities (`@babel/core` low, `brace-expansion`/`js-yaml`/ `next`/`postcss`/`sharp` high) — Differenz vermutlich Lock-Datei-Drift zwischen Workstation und 131 zum Zeitpunkt des Checks. - `npm audit fix` (ohne `--force`, da alle 6 Funde `fixAvailable: true` ohne SemVer-Major-Flag waren) → **0 Vulnerabilities**. `next` wanderte dabei minor von 16.2.9 auf 16.3.0 (im `^16.1.1`-Range, kein Breaking Change). - `npx update-browserslist-db@latest` → `caniuse-lite` aktualisiert (1.0.30001763 → 1.0.30001806), keine Target-Browser-Änderung. - Verifikation: `npx tsc --noEmit` 0 Fehler, `npm run build` erfolgreich, alle 14 Routen generiert. - `update.sh` erweitert: nach `npm ci` läuft jetzt `npm audit --audit-level=high` als **Warn-Gate** (nicht blockierend, kein Auto-Fix während des laufenden Deploys — Breaking-Change-Risiko live auf Produktivsystem wäre inakzeptabel). Bei Fund: Warnung mit Verweis auf `/tmp/npm-audit-report.txt` und Hinweis, `npm audit fix` lokal auszuführen/zu testen/zu committen statt es automatisch im Deploy zu fahren. ## Acceptance Criteria - [x] `lucide-react` auf 1.x, `tsc --noEmit` + `npm run build` grün. - [ ] `eslint` auf 10.x + `eslint-config-next` kompatibel, `npm run lint` grün. - [ ] `@types/node` auf zur Server-Node-Version passende Major-Version. - [ ] `tailwindcss` v4 + `tailwind-merge` v3 gemeinsam umgesetzt, Lint-Regel gegen `*-opacity-*`-Klassen aktiv, visueller Regressionstest durchgeführt. - [ ] `typescript` schrittweise auf 7.x, `tsc --noEmit` bei jedem Zwischenschritt grün. - [ ] Jeder Schritt einzeln auf 132 verifiziert vor 131-Deploy.