Unterstützung für Internationalisierung
Node.js bietet viele Funktionen, die das Schreiben internationalisierter Programme vereinfachen. Einige davon sind:
Gebietsschema-sensitive oder Unicode-bewusste Funktionen in der ECMAScript Language Specification:
Alle in der ECMAScript Internationalization API Specification (auch bekannt als ECMA-402) beschriebenen Funktionen:
Intl
Objekt- Gebietsschema-sensitive Methoden wie
String.prototype.localeCompare()
undDate.prototype.toLocaleString()
Unterstützung für internationalisierte Domainnamen (IDNs) des WHATWG URL Parsers
Genauere REPL Zeileneditierung
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:
Funktion | none | system-icu | small-icu | full-icu |
---|---|---|---|---|
String.prototype.normalize() | keine (Funktion ist ein No-Op) | voll | voll | voll |
String.prototype.to*Case() | voll | voll | voll | voll |
Intl | keine (Objekt existiert nicht) | teilweise/voll (abhängig vom Betriebssystem) | teilweise (nur Englisch) | voll |
String.prototype.localeCompare() | teilweise (nicht lokalisiert) | voll | voll | voll |
String.prototype.toLocale*Case() | teilweise (nicht lokalisiert) | voll | voll | voll |
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 Parser | teilweise (keine IDN-Unterstützung) | voll | voll | voll |
WHATWG URL Parser | teilweise (keine IDN-Unterstützung) | voll | voll | voll |
require('node:buffer').transcode() | keine (Funktion existiert nicht) | voll | voll | voll |
REPL | teilweise (ungenaues Bearbeiten von Zeilen) | voll | voll | voll |
require('node:util').TextDecoder | teilweise (Unterstützung für grundlegende Codierungen) | teilweise/voll (abhängig vom Betriebssystem) | teilweise (nur Unicode) | voll |
RegExp Unicode Property Escapes | keine (ungültiger RegExp -Fehler) | voll | voll | voll |
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:
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:
;`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:
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:
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:
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: