React-Frontend ausliefern, altes Vanilla-Frontend entfernt

- frontend.go: Seitenrouten liefern die index.html (no-cache), gehashte
  Assets unter /assets dauerhaft cachebar, sonst echtes 404
- /stats als Seite, /stats.html leitet per 301 weiter
- Containerfile: Node-Stage baut das Frontend nach web/
- Vite baut nach ../web (gitignored); web/ (Vanilla-JS) gelöscht
- notes/frontend.md, deploy.md angepasst

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TiXsPUqw7oeomZ8wZrQW5q
This commit is contained in:
irrlicht
2026-09-26 23:49:20 +02:00
co-authored by Claude Opus 5.5
parent 728ac9b45e
commit 9cac33d167
22 changed files with 129 additions and 1368 deletions
+5 -2
View File
@@ -27,8 +27,11 @@ Beim ersten Deployment: DB und Medien einmalig in die Volumes kopieren
podman build -t kver .
```
Multi-Stage-Build (`Containerfile`): statisches Go-Binary (CGO aus), Laufzeit-
Image ist Alpine mit unprivilegiertem Nutzer.
Multi-Stage-Build (`Containerfile`): das React-Frontend wird in einer
Node-Stage gebaut (`npm ci && npm run build`), das Go-Binary statisch (CGO
aus); das Laufzeit-Image ist Alpine mit unprivilegiertem Nutzer und enthält
nur Binary, gebautes Frontend (`web/`) und `static/`. Auf dem Server wird
also weder Node noch Go gebraucht, nur Podman.
Die Warnung `HEALTHCHECK is not supported for OCI image format` ist erwartbar:
Podman baut OCI-Images, dort gibt es kein eingebettetes HEALTHCHECK. Der
+46
View File
@@ -0,0 +1,46 @@
# Frontend (React)
Quellcode in `frontend/`: Vite, React, TypeScript, React Router, TanStack Query.
**Optik:** bewusst brutalistisch-roh. Markup, IDs und Klassen entsprechen dem
früheren Vanilla-Frontend, `frontend/src/app.css` ist das einzige Stylesheet.
Umbauten ändern Funktion, nicht Aussehen.
## Entwickeln
Zwei Terminals:
```sh
set -a; . ./dev.env; set +a; go run . # Backend auf :8081
cd frontend && npm run dev # http://localhost:5173
```
Vite reicht `/api` und `/static` ans Backend durch (`frontend/vite.config.ts`,
`changeOrigin: false` ist Pflicht, sonst scheitert jeder POST am Origin-Check).
## Bauen
`npm run build` in `frontend/` prüft die Typen und schreibt nach `../web/`
(gitignored). Von dort liefert das Go-Backend aus (`frontend.go`), lokal also
auch ohne Vite: `npm run build`, dann `go run .`.
## Aufbau
| Datei | Zweck |
|-------|-------|
| `src/api.ts` | API-Client; jeder Nicht-2xx-Status wird zu `ApiError` |
| `src/types.ts` | Typen der API-Antworten (Referenz: `notes/api.md`) |
| `src/auth.ts` | `useMe()` (eigenes Konto oder `null`), `useAuthChanged()` |
| `src/main.tsx` | Router, QueryClient |
| `src/Layout.tsx` | Header, Headerbar |
| `src/pages/*` | Startseite, Thread, Profil, Statistik |
| `src/components/*` | Feed, Beitragskarte, Votes, Repost, Login, Beitrag verfassen |
Seitenrouten des Clients (`/`, `/e/:pid`, `/u/:username`, `/stats`) müssen
auch in `routes()` (main.go) stehen, sonst liefert ein direkter Aufruf 404.
## Impressions
Das Backend zählt Seitenaufrufe beim Ausliefern der `index.html`. Navigation
innerhalb der App lädt keine Seite mehr vom Server und wird deshalb nicht
gezählt -- nur der erste Aufruf bzw. ein Reload.