Обновление данных

Библиотека Globalize использует данные проекта CLDR (Common Locale Data Repository) для локализации чисел, дат, валют, единиц измерения и других элементов интернационализации. Все форматирование в Globalize строится вокруг актуальности этих данных. При обновлении версии CLDR необходимо корректно обновлять набор JSON-файлов, следить за совместимостью модулей и контролировать структуру загружаемых локалей.

Источник данных CLDR

Globalize не содержит встроенных локализационных данных. Вместо этого библиотека опирается на пакет cldr-data, который предоставляет JSON-структуры с региональными настройками.

Типичные категории данных:

  • форматы дат;
  • числовые системы;
  • валюты;
  • правила множественного числа;
  • часовые пояса;
  • единицы измерения;
  • языковые соглашения.

Пример структуры каталога:

cldr-data/
├── main/
│   ├── en/
│   ├── fr/
│   ├── de/
│   └── ru/
├── supplemental/
└── package.json

Каждая локаль содержит собственные JSON-файлы с форматами и правилами.


Причины обновления данных

Обновление данных выполняется по нескольким причинам:

Изменения стандартов Unicode

Проект CLDR регулярно обновляется организацией Unicode. В новых версиях появляются:

  • изменения форматов дат;
  • обновлённые названия валют;
  • новые коды регионов;
  • исправления грамматических правил;
  • изменения часовых поясов.

Поддержка новых локалей

Новая версия CLDR может содержать дополнительные языки и регионы.

Исправление ошибок локализации

Некоторые правила форматирования могут быть исправлены:

Globalize.formatCurrency(1000, "RUB");

После обновления CLDR результат форматирования может измениться в соответствии с новыми стандартами.

Синхронизация с браузерами

Современные браузеры обновляют ICU и CLDR внутри JavaScript-движков. Актуальные данные позволяют избежать расхождений между сервером и клиентом.


Обновление пакета cldr-data

Установка последней версии

npm install cldr-data@latest

или:

yarn add cldr-data

Проверка установленной версии:

npm list cldr-data

Обновление Globalize

Версии 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-данных

Каталог 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 обновлён");

Обновление через CI/CD

Обновление может быть встроено в 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"));

Кэширование данных

После обновления рекомендуется очищать кэш:

  • webpack cache;
  • browser cache;
  • server-side cache;
  • CDN-кэш.

Иначе приложение может продолжать использовать старые JSON-файлы.


Изменения структуры данных

Иногда новые версии CLDR изменяют структуру JSON.

Например:

{
  "main": {
    "en": {
      "numbers": {}
    }
  }
}

Некоторые поля могут быть перенесены или переименованы.

После обновления необходимо:

  1. проверить пользовательские парсеры;
  2. обновить пути к JSON;
  3. протестировать загрузчики;
  4. проверить динамический импорт.

Динамическая загрузка локалей

При обновлении данных особенно важно учитывать ленивую загрузку.

Пример динамического импорта

async function loadLocale(locale) {
    const numbers = await import(
        `cldr-data/main/${locale}/numbers.json`
    );

    Globalize.load(numbers.default);

    Globalize.locale(locale);
}

Если структура CLDR изменится, динамические пути могут перестать работать.


Версионирование данных

Для стабильности приложения желательно фиксировать версии.

package.json

{
  "dependencies": {
    "globalize": "1.7.0",
    "cldr-data": "43.1.0"
  }
}

Использование latest может привести к неожиданным изменениям локализации.


Миграция между версиями CLDR

Крупные обновления CLDR могут содержать:

  • новые правила plural forms;
  • изменения timezone;
  • обновлённые региональные обозначения;
  • новые валюты;
  • удалённые устаревшие данные.

Перед миграцией рекомендуется:

  1. протестировать форматирование;
  2. проверить snapshots;
  3. обновить unit-тесты;
  4. проверить SSR;
  5. проверить browser bundles.

Проверка plural rules

После обновления может измениться работа множественного числа.

Пример:

const globalize = new Globalize("ru");

const plural = globalize.plural(5);

console.log(plural);

Изменения правил способны повлиять на:

  • интерфейсы;
  • переводимые сообщения;
  • ICU MessageFormat;
  • склонения.

Обновление timezone-данных

CLDR регулярно обновляет сведения о часовых поясах.

Пример форматирования:

const globalize = new Globalize("en");

console.log(
    globalize.formatDate(new Date(), {
        datetime: "medium"
    })
);

После обновления:

  • могут измениться аббревиатуры;
  • обновляются DST-правила;
  • меняются региональные зоны.

Проверка bundle-размера

Новые версии 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"
];

Проверка fallback-механизмов

CLDR использует fallback-цепочки.

Например:

en-GB → en → root

После обновления необходимо убедиться, что:

  • fallback работает корректно;
  • отсутствующие данные наследуются правильно;
  • локаль не переходит к root неожиданно.

Обновление пользовательских локалей

Некоторые приложения расширяют CLDR собственными данными.

Пример:

Globalize.load({
    main: {
        ru: {
            customData: {
                companyName: "Компания"
            }
        }
    }
});

После обновления CLDR следует проверить:

  • отсутствие конфликтов;
  • совместимость структуры;
  • корректность merge-операций.

Интеграция с webpack

При обновлении данных часто требуется пересборка.

ContextReplacementPlugin

new webpack.ContextReplacementPlugin(
    /cldr-data/,
    path.resolve(__dirname, "cldr-data")
);

Генерация предварительно скомпилированных форматтеров

После обновления CLDR желательно пересоздавать компилированные форматтеры.

Пример

const formatter = Globalize
    .dateFormatter({ datetime: "medium" });

Если форматтер был создан до обновления данных, он может использовать старые правила.


Тестирование после обновления

Наиболее важные категории тестов:

Тип теста Проверка
Unit форматирование
Integration загрузка локалей
Snapshot изменение строк
E2E работа интерфейса
SSR серверный рендеринг

Snapshot-тестирование

Обновление 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;
    }
}

Использование CDN

Некоторые приложения загружают CLDR через CDN.

Пример:

<script src="/cldr/main/ru/numbers.json"></script>

После обновления необходимо:

  • синхронизировать версии;
  • очистить CDN-кэш;
  • проверить integrity hashes.

Обновление данных на сервере

В SSR-приложениях обновление выполняется отдельно от клиента.

Пример:

Globalize.load(
    require("./locales/ru.json")
);

После деплоя сервера важно:

  • перезапустить процесс;
  • очистить memory cache;
  • обновить контейнеры.

Хранение локалей в отдельных пакетах

В больших системах локали иногда выделяются в отдельный пакет:

@company/locales

Обновление выполняется централизованно:

npm update @company/locales

Такой подход упрощает:

  • синхронизацию версий;
  • переиспользование;
  • контроль качества локализации.

Стратегии безопасного обновления

Наиболее распространённые стратегии:

Пошаговое обновление

42 → 43 → 44

Вместо:

42 → 50

Canary-деплой

Новые данные сначала получают только часть пользователей.

Feature flag

if (useNewLocaleData) {
    loadNewCLDR();
}

Проверка производительности

Новые версии CLDR могут увеличить:

  • время загрузки;
  • размер памяти;
  • объём bundle;
  • время инициализации.

Пример измерения:

console.time("globalize");

Globalize.load(data);

console.timeEnd("globalize");

Работа с пользовательским кешем форматтеров

После обновления старые форматтеры необходимо инвалидировать.

Неправильный подход:

cache[locale] = formatter;

Лучше учитывать версию данных:

cache[`${locale}-${version}`] = formatter;

Мониторинг изменений CLDR

Для отслеживания обновлений обычно контролируют:

  • changelog Unicode CLDR;
  • release notes;
  • изменения ICU;
  • обновления Globalize.

Это позволяет заранее подготовиться к возможным изменениям поведения локализации.