Svelte 5 Statisch (Runes)
Was diese Fähigkeit abdeckt
„Statisch“ bedeutet, dass das Ergebnis ein Ordner mit vorgefertigten HTML/CSS/JS-Dateien ist, die zur Laufzeit keinen Node-/Edge-Server benötigen – gehostet auf GitHub Pages, Netlify/Cloudflare/Vercel statischem Hosting, S3+CloudFront oder als lokale Dateien. Diese Einschränkung schließt +page.server.js, +server.js, Formularaktionen, hooks.server.js und jeden Code-Pfad aus, der einen laufenden Server voraussetzt. „Runes“ bedeutet, dass die Komponenten-Reaktivität mit Svelte 5s $state/$derived/$effect/$props Primitiven geschrieben wird, nicht mit Svelte 4s export let / $: / impliziter Reaktivität.
Diese beiden Einschränkungen interagieren: Ein statischer Build funktioniert nur dann sauber, wenn kein Code – auch nicht innerhalb von $effect – davon ausgeht, dass er pro Anfrage auf einem Server läuft. Behalten Sie das während des gesamten Prozesses im Hinterkopf; es ist die Quelle der meisten Fehler, wenn Menschen eine SvelteKit-App zu adapter-static migrieren.
Schritt 1 — Die richtige Projektform wählen
Fragen Sie (oder leiten Sie aus dem Kontext ab), ob die App dateibasiertes Routing, mehrere vorgerenderte Seiten oder SEO-freundliches HTML pro Route benötigt. Dies bestimmt das gesamte Setup, also überspringen Sie diesen Schritt nicht.
| Bedarf | Verwendung |
|---|---|
| Einzelseite / Dashboard / Widget / Embed, kein Routing | Einfaches Vite + Svelte (npm create vite@latest -- --template svelte-ts). Einfachstes mögliches statisches Setup – es gibt keinen Server, der versehentlich eingeführt werden kann. |
| Mehrere Routen, jede in eine eigene HTML-Datei vorgerendert, SEO ist wichtig | SvelteKit + @sveltejs/adapter-static mit prerender = true. |
| Mehrere Routen, aber SEO ist unwichtig (Internes Tool, Chrome-Erweiterung, Electron/Tauri-UI) | SvelteKit + adapter-static im SPA-Modus (eine einzelne fallback: 'index.html' Shell, clientseitiges Routing). |
Standardmäßig zu einfachem Vite+Svelte tendieren, es sei denn, Sie benötigen speziell Routing – es gibt weniger Konfigurationsmöglichkeiten, die falsch eingestellt werden können. Vollständige Setup-Schritte, Konfigurationsdateien und Deployment-Hinweise für beide Pfade finden Sie in references/static-build.md; lesen Sie diese, bevor Sie svelte.config.js / vite.config.js aus dem Gedächtnis generieren, da prerender/adapter-Optionen sich zwischen Svelte-Versionen ändern und leicht subtil falsch eingestellt werden können (z. B. trailingSlash vergessen oder ssr = false auf einer Seite setzen, die auch vorgerendert werden soll, was eine leere Shell anstelle von echtem HTML erzeugt).
Schritt 2 — Komponenten mit Runes schreiben, nicht mit Svelte 4 Syntax
Schreiben Sie niemals export let, $:, on:click oder einen einfachen writable()-Store als primäre Methode zur Verwaltung des Komponentenstatus in neuem Svelte 5 Code – diese kompilieren in den meisten Konfigurationen noch, aber es sind veraltete Muster; hier geht es speziell um Runes. Die Kernzuordnung:
| Svelte 4 | Svelte 5 |
|---|---|
let count = 0 (reaktiv, weil auf oberster Ebene) | let count = $state(0) |
$: doubled = count * 2 | let doubled = $derived(count * 2) (oder $derived.by(() => ...) für mehrzeilige Logik) |
$: { sideEffect(count) } | $effect(() => { sideEffect(count) }) |
export let name | let { name } = $props() |
export let value; bind:value (Kind mutiert) | let { value = $bindable() } = $props() |
onMount/onDestroy für DOM-only Setup/Teardown | $effect(() => { ...; return () => cleanup(); }) |
<slot name="header"> | {#snippet header()}...{/snippet} + {@render header()} |
writable()/readable() Store, $store in Komponenten | $state(...) in einem .svelte.js/.svelte.ts Modul, direkt importiert (Reaktivität funktioniert jetzt außerhalb von Komponenten) |
Lesen Sie references/runes.md, bevor Sie nicht-triviale Rune-Codes schreiben – es behandelt die Teile, die Menschen zuverlässig falsch machen: $derived muss rein bleiben (keine Seiteneffekte, keine Zustandsmutation darin), $effect darf niemals in denselben Zustand schreiben, den es liest (Endlosschleife), $state.raw für große/eingefrorene Daten, die Sie neu zuweisen statt mutieren, $effect.root/untrack für Zustand, der außerhalb von Komponenten-Lebenszyklen geteilt wird, und das genaue klassenbasierte Muster für komponentenübergreifenden/Modul-Zustand. Wenn Sie diese falsch machen, entstehen Fehler, die sich nur als seltsame Neu-Render-Schleifen oder veraltete UI zeigen, die schwer im Nachhinein zu diagnostizieren sind – besser, Sie schreiben es gleich richtig.
Wenn Sie vorhandenen Svelte 4 Code migrieren, erledigt npx sv migrate svelte-5 die mechanische Umschreibung (dies ist das aktuelle Tool; ältere Dokumentationen verweisen möglicherweise auf svelte-migrate), aber überprüfen Sie immer den Diff – die automatisierte Migration repariert zuverlässig keine Stores-als-komponentenübergreifender-Zustand-Muster oder Effekte, die abgeleitete Werte hätten sein sollen.
Schritt 3 — Die Sicherheitscheckliste anwenden
Statisches Hosting bedeutet nicht „keine Sicherheitsoberfläche“ – es entfernt serverseitige Angriffsvektoren, aber die clientseitigen (XSS, Leck von Geheimnissen, unsichere Drittanbieter-Einbettungen) liegen vollständig in Ihrer Verantwortung, da es keine serverseitige Schicht gibt, die sie abfängt. Bevor Sie eine Aufgabe abschließen, die benutzergenerierte Inhalte, {@html}, Umgebungsvariablen oder Skripte von Drittanbietern betrifft, lesen Sie references/security.md. Die wichtigsten Regeln, damit sie auch bei einer schnellen Aufgabe nicht übersehen werden:
- Übergeben Sie niemals unsanitisierte Inhalte an
{@html}. Svelte escaped automatisch alles in{expression}-Klammern, aber{@html ...}umgeht dies vollständig – es ist die häufigste XSS-Quelle in Svelte-Apps. Sanitisieren Sie mit DOMPurify (oder einer strengen Positivliste) unmittelbar vor dem Rendern, nicht früher in der Pipeline, wo es durch eine spätere Bearbeitung umgangen werden könnte. - Setzen Sie niemals ein echtes Geheimnis hinter eine Umgebungsvariable mit
VITE_-Präfix (oder SvelteKitPUBLIC_-Präfix). Vite bindet diese zur Build-Zeit in das ausgelieferte JS-Bundle ein – jeder kann sie aus den gebauten Dateien lesen. Eine reine statische App hat überhaupt keinen Server, um ein Geheimnis zu verstecken. Wenn die App einen echten API-Schlüssel benötigt, gehört der Schlüssel auf den Server des Drittanbieters oder hinter eine separate serverlose Funktion/einen Proxy, den ich woanders bereitstelle – weisen Sie mich darauf hin, anstatt den Schlüssel stillschweigend in den Client-Code einzubauen. - Setzen Sie eine Content-Security-Policy, auch wenn es keinen Server gibt, um Header zu senden. Statische Hosts unterstützen dies dennoch über ein
<meta http-equiv="Content-Security-Policy">-Tag inapp.html/index.htmloder über eine hostspezifische Header-Datei (Netlify_headers, Cloudflare Pages_headers, Vercelvercel.jsonHeaders) – siehereferences/security.mdfür beides. - Behandeln Sie jedes dynamische
href/srcals angreifergesteuert, wenn es von Benutzereingaben oder einer API-Antwort stammen kann. Svelte blockiertjavascript:-URLs inhref-Bindungen nicht – validieren/whitelisten Sie das Schema selbst. - Führen Sie
npm audit(oder ein Äquivalent) aus und fixieren Sie Lockfiles, bevor Sie ausliefern – statische Seiten liefern dennoch den gesamten Code jeder Abhängigkeit direkt an den Browser aus, daher ist eine kompromittierte Abhängigkeit eine direkte Client-seitige Kompromittierung.
Referenzdateien
references/runes.md– vollständige Rune-für-Rune-Anleitung mit korrekten/inkorrekten Mustern, klassenbasiertem gemeinsamem Zustand, TypeScript-Typisierung für Props/Snippets und der detaillierten Svelte-4-zu-5-Migrationstabelle.references/static-build.md– einfaches Vite+Svelte-Setup, SvelteKit+adapter-static-Setup (vollständiges Vorrendern und SPA-Fallback-Modi), Fallstricke bei trailing-slash/base-path und hostspezifische Deployment-Hinweise (GitHub Pages, Netlify, Cloudflare Pages, S3/CloudFront).references/security.md– vollständige Checkliste: XSS/{@html}/DOMPurify, CSP für statische Hosts (Meta-Tag +_headers-Vorlagen), Geheimnisse/Umgebungsvariablen, sichere externe Links, Abhängigkeitsprüfung, Trusted Types, localStorage/sessionStorage-Sensitivität und eine Pre-Ship-Checkliste.assets/– kopierbare Startdateien:vite.config.ts,svelte.config.js(adapter-static),_headers(CSP-Vorlage) undSecureHtml.svelte(eine DOMPurify-Wrapper-Komponente).
Ziehen Sie diese nach Bedarf heran, anstatt ihre Inhalte aus dem Gedächtnis zu reproduzieren – die Konfigurationsoptionsnamen und CSP-Direktiven-Details sind genau die Art von Details, die veralten oder falsch erinnert werden.