Поддержка интернационализации
Node.js имеет множество функций, упрощающих написание программ с поддержкой интернационализации. Вот некоторые из них:
- Функции, учитывающие локаль или поддерживающие Unicode, в спецификации языка ECMAScript:
- Вся функциональность, описанная в спецификации API интернационализации ECMAScript (она же ECMA-402):
-
объект
Intl - Методы, учитывающие локаль, например
String.prototype.localeCompare()иDate.prototype.toLocaleString()
-
объект
- Поддержка интернационализированных доменных имён (IDN) в анализаторе URL WHATWG
require('node:buffer').transcode()- Более точное редактирование строк в REPL
require('node:util').TextDecoderRegExpэкранирования свойств 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 могут быть полезны следующие ресурсы:
© 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