Поддержка интернационализации
Node.js имеет множество функций, которые облегчают создание интернационализированных программ. Некоторые из них:
- Функции, чувствительные к локали или Unicode, в Спецификации языка ECMAScript:
- Все функции, описанные в Спецификации API интернационализации ECMAScript (также известной как ECMA-402):
-
Intlобъект - Локализованные методы, такие как
String.prototype.localeCompare()иDate.prototype.toLocaleString()
-
- Поддержка интернационализированных доменных имён (IDN) в парсере URL WHATWG
require('buffer').transcode()- Более точное редактирование строки REPL
require('util').TextDecoderRegExpUnicode Property Escapes
Node.js (и его подлежащий движок V8) использует ICU для реализации этих функций на языке C/C++. Однако для поддержки всех локалей мира некоторые из них требуют очень большой файла данных ICU. Поскольку ожидается, что большинство пользователей Node.js будут использовать лишь небольшую часть функциональности ICU, Node.js по умолчанию предоставляет только подмножество полного набора данных ICU. Предоставляются несколько вариантов настройки и расширения набора данных ICU во время сборки или выполнения Node.js.
Варианты сборки Node.js
Для управления тем, как ICU используется в Node.js, при компиляции доступны четыре configure варианта. Дополнительные сведения о том, как скомпилировать Node.js, приведены в BUILDING.md.
-
--with-intl=none/--without-intl --with-intl=system-icu-
--with-intl=small-icu(по умолчанию) --with-intl=full-icu
Обзор доступных функций Node.js и JavaScript для каждого configure варианта:
none |
system-icu |
small-icu |
full-icu |
|
|---|---|---|---|---|
String.prototype.normalize() |
нет (функция является бесполезной) | полностью | полностью | полностью |
String.prototype.to*Case() |
полностью | полностью | полностью | полностью |
Intl |
нет (объект не существует) | частично/полностью (зависит от ОС) | частично (только английский язык) | полностью |
String.prototype.localeCompare() |
частично (не учитывает локаль) | полностью | полностью | полностью |
String.prototype.toLocale*Case() |
частично (не учитывает локаль) | полностью | полностью | полностью |
Number.prototype.toLocaleString() |
частично (не учитывает локаль) | частично/полностью (зависит от ОС) | частично (только английский язык) | полностью |
Date.prototype.toLocale*String() |
частично (не учитывает локаль) | частично/полностью (зависит от ОС) | частично (только английский язык) | полностью |
| Парсер URL WHATWG | частично (нет поддержки IDN) | полностью | полностью | полностью |
require('buffer').transcode() |
нет (функция не существует) | полностью | полностью | полностью |
| REPL | частично (неточное редактирование строки) | полностью | полностью | полностью |
require('util').TextDecoder |
частично (поддержка базовых кодировок) | частично/полностью (зависит от ОС) | частично (только Unicode) | полностью |
RegExp Unicode Property Escapes |
нет (ошибка RegExp) |
полностью | полностью | полностью |
Обозначение «(не учитывает локаль)» означает, что функция выполняет свою операцию так же, как и её версия без учёта локали, если она существует. Например, в режиме none, поведение функции Date.prototype.toLocaleString() идентично поведению функции Date.prototype.toString().
Отключение всех функций интернационализации (none)
Если выбран этот вариант, большинство функций интернационализации, упомянутых выше, будут недоступны в результирующем node бинарнике.
Компиляция с предварительно установленным ICU (system-icu)
Node.js может слинковаться с уже установленным на системе ICU. На самом деле, большинство дистрибутивов Linux уже имеют ICU, и этот вариант позволит повторно использовать тот же набор данных, используемый другими компонентами в ОС.
Функциональности, которые требуют только библиотеку ICU, такие как String.prototype.normalize() и парсер URL WHATWG, полностью поддерживаются в режиме system-icu. Функции, которые дополнительно требуют данных ICU для локали, такие как Intl.DateTimeFormat, могут быть полностью или частично поддерживаемы в зависимости от полноты данных локали ICU, установленных на системе.
Встраивание ограниченного набора данных ICU (small-icu)
Этот вариант позволяет слинковать результирующий бинарник со статической библиотекой ICU и включить подмножество данных ICU (как правило, только английскую локаль) в исполняемый файл node.
Функциональности, которые требуют только саму библиотеку ICU, такие как String.prototype.normalize() и парсер URL WHATWG, полностью поддерживаются в режиме small-icu. Функции, которые дополнительно требуют данных ICU для локали, такие как Intl.DateTimeFormat, как правило, работают только с английской локалью:
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));
// Prints "January"
console.log(spanish.format(january));
// Prints "M01" on small-icu
// Should print "enero" Этот режим обеспечивает хороший баланс между функциональностью и размером бинарника и является по умолчанию, если не указан флаг --with-intl . Официальные бинарники также собираются в этом режиме.
Обеспечение данных ICU во время выполнения
Если используется вариант small-icu, можно предоставить дополнительные данные локали во время выполнения, чтобы методы JS работали для всех локалей ICU. Предполагая, что файл данных хранится в /some/directory, его можно сделать доступным для ICU с помощью:
-
Переменной среды
NODE_ICU_DATA:env NODE_ICU_DATA=/some/directory node
-
Параметра командной строки
--icu-data-dir:node --icu-data-dir=/some/directory
(Если оба указаны, параметр командной строки --icu-data-dir имеет приоритет.)
ICU может автоматически обнаружить и загрузить различные форматы данных, но данные должны быть подходящими для версии ICU, а файл должен быть правильно назван. Наиболее распространённое имя файла данных — icudt6X[bl].dat, где 6X обозначает предполагаемую версию ICU, а b или l обозначает порядок байтов системы. Обратитесь к статье «ICU Data» в Руководстве пользователя ICU для получения других поддерживаемых форматов и более подробной информации о данных ICU в целом.
Модуль npm full-icu может значительно упростить установку данных ICU, обнаружив версию ICU работающего исполняемого файла node и загрузив соответствующий файл данных. После установки модуля с помощью npm i full-icu, файл данных будет доступен по адресу ./node_modules/full-icu. Этот путь можно затем передать в NODE_ICU_DATA или --icu-data-dir, как показано выше, чтобы включить полную поддержку Intl.
Встраивание всего ICU (full-icu)
Этот вариант позволяет слинковать результирующий бинарник со статической библиотекой ICU и включить полный набор данных ICU. Бинарник, созданный таким образом, не имеет дополнительных внешних зависимостей и поддерживает все локали, но может быть довольно большим. См. BUILDING.md о том, как скомпилировать бинарник с использованием этого режима.
Обнаружение поддержки интернационализации
Чтобы проверить, включен ли ICU вообще (system-icu, small-icu, или full-icu), достаточно проверить существование Intl.
const hasICU = typeof Intl === 'object';
В качестве альтернативы, проверка на process.versions.icu, свойство, определённое только при включенном ICU, тоже работает:
const hasICU = typeof process.versions.icu === 'string';
Чтобы проверить поддержку не английской локали (т.е. full-icu или system-icu), Intl.DateTimeFormat может быть хорошим отличительным фактором:
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;
}
})(); Для более подробных тестов поддержки Intl могут оказаться полезными следующие ресурсы:
-
btest402: Обычно используется для проверки правильности сборки Node.js с поддержкой
Intl. - Test262: Официальная тестовая сборка соответствия ECMAScript включает раздел, посвящённый ECMA-402.
© Joyent, Inc. and other Node contributors
Licensed under the MIT License.
Node.js is a trademark of Joyent, Inc. and is used with its permission.
We are not endorsed by or affiliated with Joyent.
https://nodejs.org/dist/latest-v12.x/docs/api/intl.html