Skip to content

Unterstützung für Internationalisierung

Node.js bietet viele Funktionen, die das Schreiben internationalisierter Programme vereinfachen. Einige davon sind:

Node.js und die zugrunde liegende V8-Engine verwenden International Components for Unicode (ICU), um diese Funktionen in nativem C/C++-Code zu implementieren. Der vollständige ICU-Datensatz wird standardmäßig von Node.js bereitgestellt. Aufgrund der Größe der ICU-Datendatei gibt es jedoch mehrere Optionen zum Anpassen des ICU-Datensatzes, entweder beim Erstellen oder Ausführen von Node.js.

Optionen zum Erstellen von Node.js

Um die Verwendung von ICU in Node.js zu steuern, stehen während der Kompilierung vier configure-Optionen zur Verfügung. Weitere Details zum Kompilieren von Node.js sind in BUILDING.md dokumentiert.

  • --with-intl=none/--without-intl
  • --with-intl=system-icu
  • --with-intl=small-icu
  • --with-intl=full-icu (Standard)

Eine Übersicht über verfügbare Node.js- und JavaScript-Funktionen für jede configure-Option:

Funktionnonesystem-icusmall-icufull-icu
String.prototype.normalize()keine (Funktion ist ein No-Op)vollvollvoll
String.prototype.to*Case()vollvollvollvoll
Intlkeine (Objekt existiert nicht)teilweise/voll (abhängig vom Betriebssystem)teilweise (nur Englisch)voll
String.prototype.localeCompare()teilweise (nicht lokalisiert)vollvollvoll
String.prototype.toLocale*Case()teilweise (nicht lokalisiert)vollvollvoll
Number.prototype.toLocaleString()teilweise (nicht lokalisiert)teilweise/voll (abhängig vom Betriebssystem)teilweise (nur Englisch)voll
Date.prototype.toLocale*String()teilweise (nicht lokalisiert)teilweise/voll (abhängig vom Betriebssystem)teilweise (nur Englisch)voll
Legacy URL Parserteilweise (keine IDN-Unterstützung)vollvollvoll
WHATWG URL Parserteilweise (keine IDN-Unterstützung)vollvollvoll
require('node:buffer').transcode()keine (Funktion existiert nicht)vollvollvoll
REPLteilweise (ungenaues Bearbeiten von Zeilen)vollvollvoll
require('node:util').TextDecoderteilweise (Unterstützung für grundlegende Codierungen)teilweise/voll (abhängig vom Betriebssystem)teilweise (nur Unicode)voll
RegExp Unicode Property Escapeskeine (ungültiger RegExp-Fehler)vollvollvoll

Die Bezeichnung "(nicht lokalisiert)" bedeutet, dass die Funktion ihre Operation genauso ausführt wie die nicht-Locale-Version der Funktion, falls vorhanden. Im Modus none ist beispielsweise die Operation von Date.prototype.toLocaleString() identisch mit der von Date.prototype.toString().

Alle Internationalisierungsfunktionen deaktivieren (none)

Wenn diese Option gewählt wird, wird ICU deaktiviert und die meisten oben genannten Internationalisierungsfunktionen sind in der resultierenden node-Binärdatei nicht verfügbar.

Build mit vorinstalliertem ICU (system-icu)

Node.js kann mit einem bereits auf dem System installierten ICU-Build verlinkt werden. Tatsächlich werden die meisten Linux-Distributionen bereits mit installiertem ICU ausgeliefert, und diese Option ermöglicht die Wiederverwendung desselben Datensatzes, der von anderen Komponenten im Betriebssystem verwendet wird.

Funktionalitäten, die nur die ICU-Bibliothek selbst benötigen, wie z. B. String.prototype.normalize() und der WHATWG URL-Parser, werden unter system-icu vollständig unterstützt. Funktionen, die zusätzlich ICU-Locale-Daten benötigen, wie z. B. Intl.DateTimeFormat, werden möglicherweise vollständig oder teilweise unterstützt, abhängig von der Vollständigkeit der auf dem System installierten ICU-Daten.

Ein beschränktes Set an ICU-Daten einbetten (small-icu)

Diese Option bewirkt, dass die resultierende Binärdatei statisch mit der ICU-Bibliothek verknüpft wird und einen Teilmenge der ICU-Daten (normalerweise nur das englische Locale) in die node-Ausführdatei einschließt.

Funktionalitäten, die nur die ICU-Bibliothek selbst benötigen, wie z. B. String.prototype.normalize() und der WHATWG URL-Parser, werden unter small-icu vollständig unterstützt. Funktionen, die zusätzlich ICU-Locale-Daten benötigen, wie z. B. Intl.DateTimeFormat, funktionieren im Allgemeinen nur mit dem englischen Locale:

js
const january = new Date(9e8)
const english = new Intl.DateTimeFormat('en', { month: 'long' })
const spanish = new Intl.DateTimeFormat('es', { month: 'long' })

console.log(english.format(january))
// Gibt "January" aus
console.log(spanish.format(january))
// Gibt entweder "M01" oder "January" unter small-icu aus, abhängig vom Standard-Locale des Benutzers
// Sollte "enero" ausgeben

Dieser Modus bietet einen Ausgleich zwischen Funktionen und Binärgröße.

Bereitstellung von ICU-Daten zur Laufzeit

Wenn die Option small-icu verwendet wird, können dennoch zusätzliche Lokalisierungsdaten zur Laufzeit bereitgestellt werden, sodass die JS-Methoden für alle ICU-Lokalisierungen funktionieren. Angenommen, die Datendatei ist unter /runtime/directory/with/dat/file gespeichert, kann sie ICU über folgende Möglichkeiten zur Verfügung gestellt werden:

  • Die Konfigurationsoption --with-icu-default-data-dir: Diese bettet nur den Pfad des Standarddatenverzeichnisses in die Binärdatei ein. Die eigentliche Datendatei wird zur Laufzeit von diesem Verzeichnispfad geladen.
  • Die Umgebungsvariable NODE_ICU_DATA:
  • Der CLI-Parameter --icu-data-dir:

Wenn mehr als eine dieser Optionen angegeben ist, hat der CLI-Parameter --icu-data-dir die höchste Priorität, dann die Umgebungsvariable NODE_ICU_DATA und dann die Konfigurationsoption --with-icu-default-data-dir.

ICU kann automatisch eine Vielzahl von Datenformaten finden und laden, aber die Daten müssen für die ICU-Version geeignet und die Datei korrekt benannt sein. Der gebräuchlichste Name für die Datendatei ist icudtX[bl].dat, wobei X die beabsichtigte ICU-Version und b oder l die Endianness des Systems angibt. Node.js schlägt fehl, wenn die erwartete Datendatei nicht aus dem angegebenen Verzeichnis gelesen werden kann. Der Name der Datendatei, die der aktuellen Node.js-Version entspricht, kann mit folgendem berechnet werden:

js
;`icudt${process.versions.icu.split('.')[0]}${os.endianness()[0].toLowerCase()}.dat`

Weitere unterstützte Formate und detailliertere Informationen zu ICU-Daten im Allgemeinen finden Sie im Artikel "ICU Data" im ICU-Benutzerhandbuch.

Das npm-Modul full-icu kann die Installation von ICU-Daten erheblich vereinfachen, indem es die ICU-Version der ausgeführten node-Executable erkennt und die entsprechende Datendatei herunterlädt. Nach der Installation des Moduls über npm i full-icu steht die Datendatei unter ./node_modules/full-icu zur Verfügung. Dieser Pfad kann dann wie oben gezeigt entweder an NODE_ICU_DATA oder --icu-data-dir übergeben werden, um die volle Intl-Unterstützung zu aktivieren.

Einbetten des gesamten ICU (full-icu)

Diese Option bewirkt, dass die resultierende Binärdatei statisch gegen ICU verlinkt und einen vollständigen Satz von ICU-Daten enthält. Eine so erstellte Binärdatei hat keine weiteren externen Abhängigkeiten und unterstützt alle Gebietsschemas, kann aber recht groß sein. Dies ist das Standardverhalten, wenn kein --with-intl-Flag übergeben wird. Die offiziellen Binärdateien werden auch in diesem Modus erstellt.

Erkennung der Internationalisierungs-Unterstützung

Um zu überprüfen, ob ICU überhaupt aktiviert ist (system-icu, small-icu oder full-icu), sollte die Überprüfung der Existenz von Intl ausreichen:

js
const hasICU = typeof Intl === 'object'

Alternativ funktioniert auch die Überprüfung von process.versions.icu, einer Eigenschaft, die nur definiert ist, wenn ICU aktiviert ist:

js
const hasICU = typeof process.versions.icu === 'string'

Um die Unterstützung für ein nicht-englisches Gebietsschema (d. h. full-icu oder system-icu) zu überprüfen, kann Intl.DateTimeFormat ein guter Unterscheidungsfaktor sein:

js
const hasFullICU = (() => {
  try {
    const january = new Date(9e8)
    const spanish = new Intl.DateTimeFormat('es', { month: 'long' })
    return spanish.format(january) === 'enero'
  } catch (err) {
    return false
  }
})()

Für ausführlichere Tests zur Intl-Unterstützung können die folgenden Ressourcen hilfreich sein:

  • btest402: Wird im Allgemeinen verwendet, um zu überprüfen, ob Node.js mit Intl-Unterstützung korrekt erstellt wurde.
  • Test262: Die offizielle Konformitätstest-Suite von ECMAScript enthält einen Abschnitt, der ECMA-402 gewidmet ist.