Библиотека Globalize использует данные проекта CLDR (Common Locale Data Repository) для локализации чисел, дат, валют, единиц измерения и других элементов интернационализации. Все форматирование в Globalize строится вокруг актуальности этих данных. При обновлении версии CLDR необходимо корректно обновлять набор JSON-файлов, следить за совместимостью модулей и контролировать структуру загружаемых локалей.
Globalize не содержит встроенных локализационных данных. Вместо этого библиотека опирается на пакет cldr-data, который предоставляет JSON-структуры с региональными настройками.
Типичные категории данных:
Пример структуры каталога:
cldr-data/
├── main/
│ ├── en/
│ ├── fr/
│ ├── de/
│ └── ru/
├── supplemental/
└── package.json
Каждая локаль содержит собственные JSON-файлы с форматами и правилами.
Обновление данных выполняется по нескольким причинам:
Проект CLDR регулярно обновляется организацией Unicode. В новых версиях появляются:
Новая версия CLDR может содержать дополнительные языки и регионы.
Некоторые правила форматирования могут быть исправлены:
Globalize.formatCurrency(1000, "RUB");
После обновления CLDR результат форматирования может измениться в соответствии с новыми стандартами.
Современные браузеры обновляют ICU и CLDR внутри JavaScript-движков. Актуальные данные позволяют избежать расхождений между сервером и клиентом.
npm install cldr-data@latest
или:
yarn add cldr-data
Проверка установленной версии:
npm list cldr-data
Версии Globalize и CLDR должны быть совместимы.
Обновление библиотеки:
npm install globalize@latest
Проверка версии:
npm list globalize
Некоторые версии Globalize рассчитаны только на определённые версии CLDR. После обновления необходимо проверить:
Пример ошибки несовместимости:
E_MISSING_CLDR: Missing required CLDR content
Причина обычно заключается в изменении структуры JSON-файлов или отсутствии обязательных модулей.
После обновления JSON-файлов данные необходимо снова передать в Globalize.
const Globalize = require("globalize");
Globalize.load(
require("cldr-data/supplemental/likelySubtags.json"),
require("cldr-data/supplemental/numberingSystems.json"),
require("cldr-data/main/en/numbers.json")
);
Если используется несколько локалей:
Globalize.load(
require("cldr-data/main/en/numbers.json"),
require("cldr-data/main/fr/numbers.json"),
require("cldr-data/main/de/numbers.json"),
require("cldr-data/main/ru/numbers.json")
);
Каталог supplemental содержит глобальные правила,
используемые всеми локалями.
Наиболее важные файлы:
| Файл | Назначение |
|---|---|
| likelySubtags.json | определение полной локали |
| numberingSystems.json | системы счисления |
| plurals.json | правила множественного числа |
| timeData.json | региональные форматы времени |
| currencyData.json | валютные данные |
Пример загрузки:
Globalize.load(
require("cldr-data/supplemental/plurals.json"),
require("cldr-data/supplemental/timeData.json"),
require("cldr-data/supplemental/currencyData.json")
);
В крупных проектах обновление данных обычно автоматизируется.
const fs = require("fs");
const path = require("path");
const childProcess = require("child_process");
childProcess.execSync("npm update cldr-data");
console.log("CLDR обновлён");
Обновление может быть встроено в pipeline:
steps:
- run: npm install
- run: npm update cldr-data
- run: npm test
После обновления желательно сравнивать результаты форматирования.
const globalize = new Globalize("fr");
console.log(globalize.formatNumber(123456.78));
const globalize = new Globalize("de");
console.log(globalize.formatDate(new Date()));
const globalize = new Globalize("ja");
console.log(globalize.formatCurrency(1000, "JPY"));
После обновления рекомендуется очищать кэш:
Иначе приложение может продолжать использовать старые JSON-файлы.
Иногда новые версии CLDR изменяют структуру JSON.
Например:
{
"main": {
"en": {
"numbers": {}
}
}
}
Некоторые поля могут быть перенесены или переименованы.
После обновления необходимо:
При обновлении данных особенно важно учитывать ленивую загрузку.
async function loadLocale(locale) {
const numbers = await import(
`cldr-data/main/${locale}/numbers.json`
);
Globalize.load(numbers.default);
Globalize.locale(locale);
}
Если структура CLDR изменится, динамические пути могут перестать работать.
Для стабильности приложения желательно фиксировать версии.
{
"dependencies": {
"globalize": "1.7.0",
"cldr-data": "43.1.0"
}
}
Использование latest может привести к неожиданным
изменениям локализации.
Крупные обновления CLDR могут содержать:
Перед миграцией рекомендуется:
После обновления может измениться работа множественного числа.
Пример:
const globalize = new Globalize("ru");
const plural = globalize.plural(5);
console.log(plural);
Изменения правил способны повлиять на:
CLDR регулярно обновляет сведения о часовых поясах.
Пример форматирования:
const globalize = new Globalize("en");
console.log(
globalize.formatDate(new Date(), {
datetime: "medium"
})
);
После обновления:
Новые версии CLDR могут значительно увеличить размер приложения.
Нежелательно подключать весь пакет:
require("cldr-data");
Лучше импортировать только нужные файлы:
require("cldr-data/main/en/numbers.json");
require("cldr-data/main/en/ca-gregorian.json");
После обновления набора данных рекомендуется проверить:
const locales = ["en", "ru", "de"];
Вместо:
const locales = [
"en",
"ru",
"de",
"fr",
"it",
"es",
"ja",
"ko",
"zh"
];
CLDR использует fallback-цепочки.
Например:
en-GB → en → root
После обновления необходимо убедиться, что:
Некоторые приложения расширяют CLDR собственными данными.
Пример:
Globalize.load({
main: {
ru: {
customData: {
companyName: "Компания"
}
}
}
});
После обновления CLDR следует проверить:
При обновлении данных часто требуется пересборка.
new webpack.ContextReplacementPlugin(
/cldr-data/,
path.resolve(__dirname, "cldr-data")
);
После обновления CLDR желательно пересоздавать компилированные форматтеры.
const formatter = Globalize
.dateFormatter({ datetime: "medium" });
Если форматтер был создан до обновления данных, он может использовать старые правила.
Наиболее важные категории тестов:
| Тип теста | Проверка |
|---|---|
| Unit | форматирование |
| Integration | загрузка локалей |
| Snapshot | изменение строк |
| E2E | работа интерфейса |
| SSR | серверный рендеринг |
Обновление CLDR часто изменяет текстовый вывод.
Пример snapshot-проверки:
expect(
globalize.formatNumber(12345.67)
).toMatchSnapshot();
Изменение snapshot после обновления может быть нормальным поведением.
Типичные ошибки:
| Ошибка | Причина |
|---|---|
| E_MISSING_CLDR | отсутствуют JSON-данные |
| E_DEFAULT_LOCALE_NOT_DEFINED | локаль не установлена |
| Cannot find module | неверный путь |
| Unsupported locale | локаль удалена |
function localeExists(locale) {
try {
require(`cldr-data/main/${locale}`);
return true;
} catch {
return false;
}
}
Некоторые приложения загружают CLDR через CDN.
Пример:
<script src="/cldr/main/ru/numbers.json"></script>
После обновления необходимо:
В SSR-приложениях обновление выполняется отдельно от клиента.
Пример:
Globalize.load(
require("./locales/ru.json")
);
После деплоя сервера важно:
В больших системах локали иногда выделяются в отдельный пакет:
@company/locales
Обновление выполняется централизованно:
npm update @company/locales
Такой подход упрощает:
Наиболее распространённые стратегии:
42 → 43 → 44
Вместо:
42 → 50
Новые данные сначала получают только часть пользователей.
if (useNewLocaleData) {
loadNewCLDR();
}
Новые версии CLDR могут увеличить:
Пример измерения:
console.time("globalize");
Globalize.load(data);
console.timeEnd("globalize");
После обновления старые форматтеры необходимо инвалидировать.
Неправильный подход:
cache[locale] = formatter;
Лучше учитывать версию данных:
cache[`${locale}-${version}`] = formatter;
Для отслеживания обновлений обычно контролируют:
Это позволяет заранее подготовиться к возможным изменениям поведения локализации.