Поддержка интернационализации
Node.js имеет множество функций, которые упрощают написание интернационализированных программ. Некоторые из них:
Функции, чувствительные к локали или поддерживающие Unicode, в ECMAScript Language Specification:
Все функции, описанные в ECMAScript Internationalization API Specification (aka ECMA-402):
- Объект
Intl
- Методы, чувствительные к локали, такие как
String.prototype.localeCompare()
иDate.prototype.toLocaleString()
- Объект
Поддержка интернационализированных доменных имен (IDN) в WHATWG URL parser
Более точное редактирование строк в REPL
Node.js и базовый движок V8 используют International Components for Unicode (ICU) для реализации этих функций в нативном C/C++ коде. Полный набор данных 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() | частичная (без учета локали) | частичная/полная (зависит от ОС) | частичная (только английский) | полная |
Legacy URL Parser | частичная (нет поддержки IDN) | полная | полная | полная |
WHATWG URL Parser | частичная (нет поддержки IDN) | полная | полная | полная |
require('node:buffer').transcode() | отсутствует (функция не существует) | полная | полная | полная |
REPL | частичная (неточное редактирование строк) | полная | полная | полная |
require('node:util').TextDecoder | частичная (поддержка базовых кодировок) | частичная/полная (зависит от ОС) | частичная (только Unicode) | полная |
RegExp Unicode Property Escapes | отсутствует (недопустимая ошибка RegExp ) | полная | полная | полная |
Обозначение "(без учета локали)" означает, что функция выполняет свою операцию так же, как и версия функции без Locale , если таковая существует. Например, в режиме none операция Date.prototype.toLocaleString() идентична операции Date.prototype.toString() . |
Отключение всех функций интернационализации (none
)
Если выбран этот параметр, ICU отключается, и большинство функций интернационализации, упомянутых выше, будут недоступны в результирующем бинарном файле node
.
Сборка с предварительно установленной ICU (system-icu
)
Node.js может быть связан с ICU, уже установленной в системе. Фактически, большинство дистрибутивов Linux уже поставляются с установленной ICU, и этот параметр позволит повторно использовать тот же набор данных, который используется другими компонентами ОС.
Функциональные возможности, требующие только саму библиотеку ICU, такие как String.prototype.normalize()
и WHATWG URL parser, полностью поддерживаются в режиме system-icu
. Функции, требующие дополнительно данные локали ICU, такие как Intl.DateTimeFormat
, могут поддерживаться полностью или частично, в зависимости от полноты данных ICU, установленных в системе.
Встраивание ограниченного набора данных ICU (small-icu
)
Этот параметр позволяет результирующему бинарному файлу статически связываться с библиотекой ICU и включает подмножество данных ICU (обычно только английскую локаль) в исполняемый файл node
.
Функциональные возможности, требующие только саму библиотеку ICU, такие как String.prototype.normalize()
и WHATWG URL parser, полностью поддерживаются в режиме 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 either "M01" or "January" on small-icu, depending on the user’s default locale
// Should print "enero"
Этот режим обеспечивает баланс между функциями и размером бинарного файла.
Предоставление данных ICU во время выполнения
Если используется опция small-icu
, то можно предоставить дополнительные данные локали во время выполнения, чтобы методы JS работали для всех локалей ICU. Предположим, что файл данных хранится в /runtime/directory/with/dat/file
, он может быть предоставлен ICU через:
- Опцию конфигурации
--with-icu-default-data-dir
: Она только встраивает путь к каталогу данных по умолчанию в бинарный файл. Фактический файл данных будет загружаться во время выполнения из этого каталога. - Переменную окружения
NODE_ICU_DATA
: - Параметр CLI
--icu-data-dir
:
Когда указано более одного из них, параметр CLI --icu-data-dir
имеет наивысший приоритет, затем переменная окружения NODE_ICU_DATA
, затем опция конфигурации --with-icu-default-data-dir
.
ICU может автоматически находить и загружать различные форматы данных, но данные должны соответствовать версии ICU, а файл должен быть правильно назван. Наиболее распространенное имя для файла данных - icudtX[bl].dat
, где X
обозначает предполагаемую версию ICU, а b
или l
указывает на порядок байтов системы. Node.js не сможет загрузиться, если ожидаемый файл данных не может быть прочитан из указанного каталога. Имя файла данных, соответствующего текущей версии Node.js, можно вычислить с помощью:
`icudt${process.versions.icu.split('.')[0]}${os.endianness()[0].toLowerCase()}.dat`;
Ознакомьтесь со статьей "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. Двоичный файл, созданный таким образом, не имеет никаких дополнительных внешних зависимостей и поддерживает все локали, но может быть довольно большим. Это поведение по умолчанию, если не передан флаг --with-intl
. Официальные бинарные файлы также создаются в этом режиме.
Обнаружение поддержки интернационализации
Чтобы проверить, включен ли 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
могут оказаться полезными следующие ресурсы: