Stellen Sie Ihre Frage und erhalten Sie einen Resümee des Dokuments, indem Sie diese Seite und den AI-Anbieter Ihrer Wahl referenzieren
Der Inhalt dieser Seite wurde mit einer KI übersetzt.
Den englischen Originaltext ansehenWenn Sie eine Idee haben, um diese Dokumentation zu verbessern, zögern Sie bitte nicht, durch das Einreichen eines Pull-Requests auf GitHub beizutragen.
GitHub-Link zur DokumentationMarkdown des Dokuments in die Zwischenablage kopieren
Vite i18n: Was an Vite liegt, nicht an Ihrem Framework
Die meisten „Vite i18n“-Tutorials sind in Wahrheit React- oder Vue-Tutorials, die zufällig Vite verwenden. Dieser Artikel beleuchtet die darunterliegende Schicht: Wie Kataloge importiert werden, was Rollup damit anstellt und warum das von Ihnen geschriebene Lazy Loading in Wirklichkeit gar nicht lazy ist.
Inhaltsverzeichnis
Statischer Import ist der Standard, und er ist synchron
Das simpelste Setup importiert jeden Katalog am Dateianfang eines Moduls:
Kopieren Sie den Code in die Zwischenablage
Damit landen drei Kataloge direkt im initialen Entry-Chunk, auf jeder Seite, für jeden Nutzer. Bei zwei Sprachen und hundert Texten fällt das kaum ins Gewicht. Bei zehn Sprachen wird es zum größten vermeidbaren Kostenfaktor im gesamten Bundle.
import.meta.glob und das Flag, das fast jeder falsch setzt
Vites Glob-Import ist die übliche Lösung:
Kopieren Sie den Code in die Zwischenablage
Lazy Loading ist der Standard: Jeder Eintrag ist eine Funktion, die einen dynamischen Import zurückgibt, und Rollup erzeugt einen eigenen Chunk pro Datei. Das Hinzufügen von { eager: true } bettet hingegen alle Dateien direkt in das aufrufende Modul ein, also genau das, was Sie eigentlich vermeiden wollten:
Kopieren Sie den Code in die Zwischenablage
Die Falle: Beide Varianten funktionieren in der lokalen Entwicklung, da Vite Module ungebündelt ausliefert. Der Unterschied wird erst im Ordner dist sichtbar. Prüfen Sie dies mit npx vite build && npx vite preview und analysieren Sie, was der Entry-Chunk tatsächlich enthält.
Aufteilung nach Routen trennt selten sauber
Dies ist das Verhalten, das Entwickler oft überrascht. Sie strukturieren Kataloge nach Seiten:
Kopieren Sie den Code in die Zwischenablage
Wenn nun zwei Routen checkout.json importieren, hebt Rollup diese Datei in einen gemeinsamen Shared Chunk, der von beiden Seiten geladen wird. Rollups Chunking orientiert sich am Modulgraphen, nicht an Ihren Verzeichnisnamen: Jedes Modul, das von mehr als einem Einstiegspunkt erreichbar ist, wird als gemeinsame Abhängigkeit gebündelt. Eine dritte Route ändert daran nichts, und eine vierte führt womöglich zu einer ganz anderen Aufteilung.
Ein Aufteilen nach Routen funktioniert folglich nur, wenn der Import-Graph strikt disjunkt ist. Wenn Bundle-Größen zählen, prüfen Sie das Ergebnis, statt Vermutungen anzustellen:
Kopieren Sie den Code in die Zwischenablage
Müssen Sie Chunk-Grenzen erzwingen, bietet build.rollupOptions.output.manualChunks den nötigen Hebel, allerdings zum Preis manueller Pflege.
Kataloge aktualisieren sich nicht per Hot Reload (HMR)
Ändern Sie eine Komponente, tauscht Vite sie sofort aus. Ändern Sie locales/fr.json, passiert je nach Import-Art gar nichts. Dynamisch importiertes JSON besitzt keine HMR-Grenze, weshalb der Modulgraph abhängige Konsumenten nicht invalidieren kann.
Viele Entwickler starten den Dev-Server bei Textänderungen neu, ohne zu wissen, dass sich dies vermeiden lässt. Die Lösung liegt beim i18n-Plugin: Es muss das HMR-Update annehmen und neue Meldungen in die laufende App einspielen. Achten Sie bei der Bibliotheksauswahl darauf, ob das Vite-Plugin dies beherrscht, da es über den täglichen Komfort im Entwicklungsprozess entscheidet.
define brennt die Sprache fest in den Build ein
Es ist verlockend, die Standardsprache zur Build-Zeit festzulegen:
Kopieren Sie den Code in die Zwischenablage
define führt eine reine Textersetzung zur Build-Zeit durch. Der Wert, der beim Kompilieren vorliegt, wird fest ausgeliefert, was einen separaten Build pro Sprache erzwingt. Das ist eine legitime Strategie, wie sie etwa Angulars natives i18n verfolgt, aber ungeeignet, wenn ein einziges Deployment alle Sprachen bedienen soll.
Werte, die pro Anfrage variieren können, gehören nicht in define, sondern müssen zur Laufzeit aufgelöst werden.
Parsing von Meldungen in die Build-Phase verlagern
Jede ausgereifte Lösung in diesem Ökosystem verfolgt letztlich denselben Ansatz: Meldungen nicht mehr im Browser zu parsen.
Tabelle in einem Modal öffnen, um alle Daten übersichtlich anzuzeigen
| Plugin | Was zur Build-Zeit erledigt wird |
|---|---|
@intlify/unplugin-vue-i18n | Kompiliert vue-i18n-Meldungen zu Renderfunktionen (reines Runtime-Paket) |
| Lingui (Makro + Plugin) | Extrahiert und kompiliert Kataloge, ersetzt Makros durch Meldungs-IDs |
| Paraglide (inlang) | Kompiliert jede Meldung in eine eigene tree-shakable Funktion |
vite-intlayer | Erstellt komponentenbezogene Wörterbücher, bereinigt und minifiziert |
Der doppelte Vorteil: Der Runtime-Compiler entfällt im finalen Bundle, und ungenutzte Einträge können statisch entfernt werden. Der Preis dafür: Sowohl Dev-Server als auch CI benötigen das Plugin, und ein reines tsc oder Test-Runner ohne Vite erfordern zusätzliche Konfigurationsschritte.
vue-i18n verdeutlicht den Vorteil: Ohne @intlify/unplugin-vue-i18n liefern Sie einen Compiler aus, der intern new Function aufruft, was unnötige Bytes kostet und Probleme mit Content Security Policies (CSP) verursachen kann.
SSR: Niemals den Sprachstatus auf Modulebene halten
Wenn Sie SSR nutzen, sei es über ein Framework oder vite-plugin-ssr, gilt eine strikte Regel: Eine Variable auf Modulebene, die die aktuelle Sprache speichert, wird von allen parallelen Anfragen desselben Serverprozesses geteilt.
Kopieren Sie den Code in die Zwischenablage
Greifen zwei Nutzer gleichzeitig auf den Server zu, kommt es zu einer Race Condition, und einer erhält die Sprache des anderen. In der lokalen Entwicklung tritt dies nicht auf, da Sie der einzige Nutzer sind. Lösen Sie die Locale pro Anfrage auf und übergeben Sie sie explizit per Kontext oder über den anfragespezifischen Speicher Ihres Frameworks.
Das Vite-Plugin von Intlayer
Intlayer registriert ein einzelnes Plugin, das Wörterbuch-Build, Dev-Mode-Watching und die Optimierungs-Pipeline übernimmt:
Kopieren Sie den Code in die Zwischenablage
Import-Rewriting, Purge und Minify sind standardmäßig aktiv. Zwei wichtige Optionen befinden sich in intlayer.config.ts:
Kopieren Sie den Code in die Zwischenablage
Da Inhalte pro Komponente statt in großen Sprachdateien deklariert werden, verfügt der Purge-Durchlauf über einen echten Modulgraphen, was das Entfernen ungenutzter Texte sicher macht. Der Nachteil: Das Plugin ist überall dort zwingend erforderlich, wo Code kompiliert wird, inklusive CI und Test-Suites. Details finden sich in der Bundle-Optimierung.
Häufige Fehler
{ eager: true }bei einem Glob für Lazy Loading. Funktioniert in Dev, liefert in Produktion alle Sprachen aus.- Ordnerstrukturen für Chunks halten. Rollup folgt Imports, keinen Verzeichnissen. Messen Sie Ihr Bundle.
- Dev-Server bei Textänderungen neu starten. Symptom eines fehlenden HMR-Handlers.
- Die Locale in
definefestschreiben. Zwingt Sie zu einem separaten Build pro Sprache. - Sprachstatus auf Modulebene bei SSR. Führt zu Lecks zwischen Anfragen, die lokal nicht auftreten.
- Performance auf dem Dev-Server bewerten. Ungebündelte Module sagen nichts über das finale Bundle aus.
Weiterführende Ressourcen
- Bundle-Optimierung: Purge, Minify und was im Browser ankommt
- Framework-Benchmarkberichte
- Konfigurationsreferenz
- Intlayer mit Vite und React einrichten
- i18next-Kompatibilitätsadapter
- React i18n: Wie das Provider-Modell funktioniert
- Vue i18n: Funktionsweise und Schwachstellen
- Komponentenbasierte vs. zentrale i18n
Kommentare
Noch keine Kommentare. Seien Sie der Erste, der seine Gedanken teilt.
