Spec-Zone.ru › Node.js 24 LTS

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

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

  • Функции, учитывающие локаль или поддерживающие Unicode, в спецификации языка ECMAScript:
    • String.prototype.normalize()
    • String.prototype.toLowerCase()
    • String.prototype.toUpperCase()
  • Вся функциональность, описанная в спецификации API интернационализации ECMAScript (она же ECMA-402):
    • объект Intl
    • Методы, учитывающие локаль, например String.prototype.localeCompare() и Date.prototype.toLocaleString()
  • Поддержка интернационализированных доменных имён (IDN) в анализаторе URL WHATWG
  • require('node:buffer').transcode()
  • Более точное редактирование строк в REPL
  • require('node:util').TextDecoder
  • RegExp экранирования свойств Unicode

Node.js и базовый движок V8 используют международные компоненты для Unicode (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 экранирования свойств Unicode отсутствует (ошибка недопустимого RegExp) полная полная полная

Пометка «не учитывает локаль» означает, что функция выполняет операцию так же, как версия функции без поддержки Locale, если такая версия существует. Например, в режиме none операция Date.prototype.toLocaleString() идентична операции Date.prototype.toString().

Отключение всех функций интернационализации (none)

При выборе этого параметра ICU отключается, и большинство упомянутых выше функций интернационализации будут недоступны в полученном двоичном файле node.

Сборка с предустановленной ICU (system-icu)

Node.js может быть связан с уже установленной в системе сборкой ICU. На самом деле ICU уже входит в состав большинства дистрибутивов Linux, и этот вариант позволяет повторно использовать тот же набор данных, что и другие компоненты ОС.

Функции, которым нужна только библиотека 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 either "M01" or "January" on small-icu, depending on the user’s default locale
// Should print "enero" copy

Этот режим обеспечивает баланс между набором функций и размером двоичного файла.

Предоставление данных ICU во время выполнения

Если используется параметр small-icu, во время выполнения можно предоставить дополнительные данные о локалях, чтобы методы JS работали со всеми локалями ICU. Если файл данных находится по пути /runtime/directory/with/dat/file, его можно предоставить ICU одним из следующих способов:

  • Параметр конфигурации --with-icu-default-data-dir:

    ./configure --with-icu-default-data-dir=/runtime/directory/with/dat/file --with-intl=small-icu copy

    В двоичный файл встраивается только путь к каталогу данных по умолчанию. Сам файл данных загружается во время выполнения из этого каталога.

  • Переменная среды NODE_ICU_DATA:

    env NODE_ICU_DATA=/runtime/directory/with/dat/file node copy
  • Параметр командной строки --icu-data-dir:

    node --icu-data-dir=/runtime/directory/with/dat/file copy

Если указано несколько вариантов, параметр командной строки --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`; copy

Дополнительные сведения о данных 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'; copy

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

const hasICU = typeof process.versions.icu === 'string'; copy

Чтобы проверить поддержку нелокальной английской локали (то есть 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;
  }
})(); copy

Для более подробной проверки поддержки 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-v24.x/docs/api/intl.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API