Поддержка интернационализации
Node.js имеет множество функций, упрощающих написание интернационализированных программ. Некоторые из них:
Функции, учитывающие языковые стандарты или Юникод, в Спецификации языка ECMAScript:
Весь функционал, описанный в Спецификации API интернационализации ECMAScript (также известной как ECMA-402):
- Объект
Intl
- Методы, учитывающие языковые стандарты, такие как
String.prototype.localeCompare()
иDate.prototype.toLocaleString()
- Объект
Поддержка интернационализированных доменных имён (IDN) в парсере URL WHATWG
Более точное редактирование строк в REPL
Node.js и используемый в его основе движок V8 используют Международные компоненты для Юникода (ICU) для реализации этих функций в нативном коде C/C++. По умолчанию Node.js предоставляет полный набор данных ICU. Однако, из-за размера файла данных 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 | частичная (нет поддержки IDN) | полная | полная | полная |
Синтаксический анализатор URL WHATWG | частичная (нет поддержки IDN) | полная | полная | полная |
require('node:buffer').transcode() | отсутствует (функция не существует) | полная | полная | полная |
REPL | частичная (неточное редактирование строк) | полная | полная | полная |
require('node:util').TextDecoder | частичная (поддержка базовых кодировок) | частичная/полная (зависит от ОС) | частичная (только Unicode) | полная |
Управляющие последовательности свойств Юникода RegExp | отсутствует (ошибка RegExp ) | полная | полная | полная |
Пометка «(не учитывает язык)» означает, что функция выполняет свою операцию так же, как и не Locale
версия функции, если она существует. Например, в режиме none
операция Date.prototype.toLocaleString()
идентична операции Date.prototype.toString()
.
Отключение всех функций интернационализации (none
)
Если выбран этот параметр, ICU отключается, и большинство функций интернационализации, упомянутых выше, будут недоступны в результирующем бинарном файле 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))
// Выводит "January"
console.log(spanish.format(january))
// Выводит либо "M01", либо "January" в small-icu, в зависимости от локальной настройки пользователя по умолчанию
// Должно выводить "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" в руководстве пользователя 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
могут быть полезны следующие ресурсы: