Skip to content

Поддержка интернационализации

Node.js имеет множество функций, упрощающих написание интернационализированных программ. Некоторые из них:

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:

Функцияnonesystem-icusmall-icufull-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, обычно работают только с английской локалью:

js
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, можно вычислить с помощью:

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:

js
const hasICU = typeof Intl === 'object'

В качестве альтернативы можно проверить process.versions.icu, свойство, определяемое только при включенном ICU:

js
const hasICU = typeof process.versions.icu === 'string'

Чтобы проверить поддержку локали, отличной от английской (т.е. full-icu или system-icu), Intl.DateTimeFormat может быть хорошим отличительным фактором:

js
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.