Поддержка интернационализации
Node.js обладает множеством функций, которые упрощают написание интернационализированных программ. Некоторые из них:
- Функции, чувствительные к локали или работающие с Unicode, в спецификации языка ECMAScript Спецификация языка ECMAScript:
- Вся функциональность, описанная в Спецификации ECMAScript Internationalization API (также известной как ECMA-402):
- Объект
Intl - Локально-чувствительные методы, такие как
String.prototype.localeCompare()иDate.prototype.toLocaleString()
- Объект
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() | частичный (не учитывает локаль) | частичный/полный (зависит от ОС) | частичный (только английский) | полный |
Примечание: Обозначение «(не учитывает локаль)» означает, что функция выполняет свою операцию так же, как и нелокальная версия функции, если она существует. Например, в режиме none, работа Date.prototype.toLocaleString() идентична работе Date.prototype.toString().
Отключение всех функций интернационализации (none)
Если выбран этот вариант, большинство функций интернационализации, упомянутых выше, будут недоступны в результирующем node двоичном файле.
Компиляция с предварительно установленным ICU (system-icu)
Node.js может ссылаться на сборку ICU, уже установленную в системе. Фактически, большинство дистрибутивов Linux уже поставляются с установленным ICU, и этот вариант позволит повторно использовать тот же набор данных, используемый другими компонентами в ОС.
Функции, которые требуют только библиотеки ICU, такие как String.prototype.normalize(), полностью поддерживаются в system-icu. Функции, которые, помимо этого, требуют данных локали ICU, такие как Intl.DateTimeFormat, могут быть полностью или частично поддерживаемы в зависимости от полноты данных локали ICU, установленных в системе.
Встраивание ограниченного набора данных ICU (small-icu)
Этот вариант позволяет статически ссылаться на библиотеку ICU в результирующем двоичном файле и включает подмножество данных ICU (обычно только английскую локаль) в исполняемый файл node.
Функции, которые требуют только самой библиотеки ICU, такие как String.prototype.normalize(), полностью поддерживаются в 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 "January" or "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, а файл должен иметь правильное имя. Наиболее распространённым именем файла данных является icudt5X[bl].dat, где 5X обозначает целевую версию 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-v6.x/docs/api/intl.html