Spec-Zone.ru › Node.js

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

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

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

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) полная полная полная

Пометка «(не локализованная)» означает, что функция выполняет свои действия так же, как и нелокализованная версия функции, если она существует. Например, в режиме 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));
// 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 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'; 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/api/intl.html

Spec-Zone.ru

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