frontend: Projektgerüst mit Vite — Single-HTML in ES-Module + Bündelung

Erster Schritt der Modularisierung (ROADMAP „tragfähige Codebasis",
TASKS Phase 1). Der bisher einzelne index.html-Prototyp wird zur Vite-App:

- CSS -> src/style.css, gesamtes JS -> src/app.js (noch als ein Modul;
  Parser/Renderer werden in den folgenden Checkboxen herausgelöst).
- index.html ist der Vite-Entry (<script type="module" src="/src/app.js">).
- npm run build (vite + vite-plugin-singlefile) inlint JS+CSS+Favicon (als
  data:-URI) in EINE self-contained dist/index.html -> bleibt file://-tauglich.
- Vitest als Testrunner eingerichtet (tests/, passWithNoTests bis Schritt 2/3).
- Pages-Workflow: Node + npm ci + npm test + npm run build, deployt dist/;
  Favicon-sed entfällt (inline), nur ../LICENSE + Footer-Version bleiben.
- .claude/launch.json auf Vite-Dev-Server (Port 8137) umgestellt.

Entscheidung als D19 dokumentiert (weicht D11 „kein Build-Zwang" bewusst auf,
hält aber D16 file://-Versprechen über die gebündelte Datei). README (de/en)
und frontend/CLAUDE.md um Dev-/Build-/Test-Workflow ergänzt.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
mhoennig
2026-07-21 20:47:23 +02:00
co-authored by Claude Opus 4.8
parent ad57707dbc
commit 78d1000f61
14 changed files with 3938 additions and 1883 deletions
+37
View File
@@ -214,3 +214,40 @@ Knoten von seiner Linie von oben abgetrennt. Fix: `ul.or>li.has-and` bekommt
vertikal **symmetrisches** Padding (Mitte bleibt bei 50 %), der Abzweig
(`::before`) und die Rail-Endkante (`:last-child::after`) werden auf 50 %
gesetzt — analog zu den bereits zentrierten all-of-Zwischenknoten.
## D19 — Modularisierung mit Vite-Bündelung zu einer self-contained Datei
Das Nahziel „tragfähige Codebasis" (ROADMAP) verlangt, den Single-HTML-
Prototyp in headless nutzbare Module (`parser`, `model`, `render`, `app`) zu
zerlegen und gegen SPEC zu testen. Die Zwickmühle: **modulare Einzeldateien**,
**`file://`-Tauglichkeit** (D16) und **kein Build** (D11) sind nicht gleichzeitig
erfüllbar — ES-`import` über `file://` blockt der Browser (CORS).
**Entscheidung: Vite als Bündler/Testrunner.** `frontend/src/*.js` sind echte
ES-Module und die Quelle der Wahrheit; `frontend/index.html` lädt im Dev-Server
per `<script type="module">`. `npm run build` (Vite + `vite-plugin-singlefile`)
inlint **alle** Module, das CSS und das Favicon (als `data:`-URI) in **eine**
`dist/index.html` — damit bleibt das `file://`-Versprechen aus D16 erhalten
(die gebaute Datei ist standalone), und der Deploy lädt nichts extern nach.
Damit wird **D11 („kein Build-Zwang") bewusst aufgeweicht**: Zum *Weiter­ent­
wickeln/Testen* braucht es nun Node + Vite (Dev-Abhängigkeiten, keine
Laufzeit-Abhängigkeiten — das Ergebnis ist reines HTML/CSS/JS ohne Framework).
Das *Ergebnis* bleibt im Geist von D11: eine einzelne, framework-freie Datei,
die überall ohne Server läuft. Verworfene Alternativen:
- **ES-Module ohne Build:** bräche `file://` (Dev-Server-Zwang lokal) — verwarf
der Nutzer, weil das lokale Öffnen erhalten bleiben soll.
- **Klassische `<script>`+Globals:** hielte `file://` ohne Build, ist aber kein
echtes ESM und erschwert headless-Tests/Tree-Shaking.
**Deploy (D16-Fortschreibung):** Der Pages-Workflow richtet Node ein, führt
`npm ci` + `npm test` (Vitest) + `npm run build` aus und nimmt
`frontend/dist/index.html`. Die frühere `sed`-Kur der `../docs/brand/`-Pfade
entfällt (Favicon inline); nur der Laufzeit-Link `../LICENSE` und die
Footer-Version werden weiter auf der Site-Kopie gesetzt. Schlägt der Testlauf
fehl, wird nicht deployt (der frühere auskommentierte Platzhalter ist nun
aktiv).
(Favicon-Inlining: ein kleiner `transformIndexHtml`-Plugin in `vite.config.js`
liest `../docs/brand/favicon.svg` und ersetzt den `<link rel="icon">` durch eine
`data:`-URI — so bleibt die Brand-Quelle unverändert und die Ausgabe eine
einzige Datei.)