Загрузка данных CLDR

Библиотека Globalize построена поверх стандарта CLDR (Unicode Common Locale Data Repository), который содержит локализационные данные для различных языков и регионов. Эти данные не встроены в библиотеку по умолчанию, а подключаются явно, что позволяет контролировать объём загружаемых ресурсов и уменьшать размер приложения.

CLDR-данные в Globalize делятся на две ключевые категории:

  • main (основные данные локали) — специфичные для языка и региона наборы
  • supplemental (дополнительные данные) — универсальные вспомогательные структуры

Разделение обусловлено тем, что supplemental-данные используются сразу несколькими локалями, тогда как main-дата привязана к конкретной культуре.


Источники CLDR-данных в JavaScript-проектах

На практике CLDR-данные чаще всего берутся из npm-пакета:

cldr-data

Он содержит уже подготовленные JSON-файлы, соответствующие стандарту CLDR. Эти файлы могут импортироваться напрямую через require или import, в зависимости от сборщика.

Структура пакета:

cldr-data/
  main/
    en/
    ru/
    fr/
  supplemental/

Каждая локаль в main содержит набор JSON-файлов, разбитых по категориям: числа, валюты, даты и т.д.


Подключение Globalize и загрузка CLDR

Globalize не работает без предварительной загрузки CLDR. Основной принцип состоит в том, что сначала загружаются данные, затем инициализируются форматтеры.

const Globalize = require("globalize");
const cldrData = require("cldr-data");

После этого выполняется загрузка supplemental-данных.


Supplemental CLDR-данные

Supplemental-данные являются обязательной основой для работы Globalize. Без них невозможна корректная работа с локалями, числами и календарями.

Ключевые компоненты:

likelySubtags

Используется для автоматического расширения локали.

Globalize.load(
  require("cldr-data/supplemental/likelySubtags")
);

Функция обеспечивает преобразование упрощённых локалей:

  • enen-Latn-US
  • ruru-Cyrl-RU

Это необходимо для унификации обработки данных.


numberingSystems

Определяет системы нумерации, используемые в разных культурах.

Globalize.load(
  require("cldr-data/supplemental/numberingSystems")
);

Поддерживаются различные системы:

  • латинская (0–9)
  • арабская
  • индийская

Globalize использует эти данные для корректного отображения чисел.


timeData и weekData

Эти структуры описывают особенности календарных систем:

Globalize.load(
  require("cldr-data/supplemental/timeData"),
  require("cldr-data/supplemental/weekData")
);

Содержат информацию о:

  • первом дне недели
  • выходных днях
  • локальных правилах календаря

currencyData и plurals

Финансовая и грамматическая локализация требует дополнительных данных:

Globalize.load(
  require("cldr-data/supplemental/currencyData"),
  require("cldr-data/supplemental/plurals")
);

Plurals определяют правила множественного числа, которые отличаются в разных языках.


Загрузка main-данных локали

После загрузки supplemental необходимо подключить конкретные языковые данные. Пример для английской локали:

Globalize.load(
  require("cldr-data/main/en/ca-gregorian"),
  require("cldr-data/main/en/numbers"),
  require("cldr-data/main/en/currencies"),
  require("cldr-data/main/en/timeZoneNames")
);

Каждый файл отвечает за отдельный аспект локализации:

  • ca-gregorian — календарная система
  • numbers — форматирование чисел
  • currencies — валюты
  • timeZoneNames — названия временных зон

Загрузка нескольких локалей

Globalize поддерживает мультилингвальные приложения, в которых данные загружаются сразу для нескольких языков.

Globalize.load(
  require("cldr-data/main/en/numbers"),
  require("cldr-data/main/ru/numbers"),
  require("cldr-data/main/fr/numbers")
);

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


Инициализация локали через Globalize

После загрузки CLDR необходимо задать активную локаль:

Globalize.locale("ru");

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

Важно, что без предварительно загруженных CLDR-данных вызов локализации приводит к ошибкам или некорректным результатам.


Полный порядок инициализации CLDR

Корректная последовательность загрузки критична:

1. Загрузка библиотеки

const Globalize = require("globalize");

2. Загрузка supplemental-данных

Globalize.load(
  require("cldr-data/supplemental/likelySubtags"),
  require("cldr-data/supplemental/numberingSystems"),
  require("cldr-data/supplemental/timeData"),
  require("cldr-data/supplemental/weekData"),
  require("cldr-data/supplemental/currencyData"),
  require("cldr-data/supplemental/plurals")
);

3. Загрузка main-данных нужных локалей

Globalize.load(
  require("cldr-data/main/ru/numbers"),
  require("cldr-data/main/ru/currencies"),
  require("cldr-data/main/ru/ca-gregorian"),

  require("cldr-data/main/en/numbers"),
  require("cldr-data/main/en/currencies"),
  require("cldr-data/main/en/ca-gregorian")
);

4. Установка локали

Globalize.locale("ru");

Разделение данных и производительность

Архитектура CLDR в Globalize ориентирована на ленивую загрузку данных. Это позволяет:

  • уменьшить начальный размер бандла
  • загружать только необходимые локали
  • кэшировать уже загруженные данные

В крупных приложениях используется динамическая подгрузка локалей:

async function loadLocale(locale) {
  Globalize.load(
    require(`cldr-data/main/${locale}/numbers`),
    require(`cldr-data/main/${locale}/currencies`),
    require(`cldr-data/main/${locale}/ca-gregorian`)
  );

  Globalize.locale(locale);
}

Структура CLDR-JSON файлов

CLDR-файлы представляют собой строго структурированные JSON-документы. Пример логики:

  • иерархическая организация ключей
  • разделение по категориям
  • отсутствие логики исполнения (только данные)

Фрагмент условной структуры:

{
  "main": {
    "en": {
      "numbers": {
        "defaultNumberingSystem": "latn",
        "symbols-numberSystem-latn": {
          "decimal": ".",
          "group": ","
        }
      }
    }
  }
}

Globalize не интерпретирует JSON как код — он лишь индексирует и использует значения.


Обработка отсутствующих данных

Если для локали отсутствует конкретный файл, Globalize может использовать fallback через likelySubtags, однако поведение зависит от доступных supplemental-данных.

Типичный сценарий:

  • отсутствует en-GB
  • используется en
  • затем применяется расширение через CLDR-правила

Ошибки загрузки CLDR

Неполная или некорректная загрузка CLDR приводит к характерным проблемам:

  • невозможность форматирования дат
  • ошибки при форматировании валют
  • отсутствие правил множественного числа
  • сбои при определении локали

Наиболее частая причина — отсутствие supplemental-данных, особенно likelySubtags.


Оптимизация загрузки CLDR

В крупных приложениях используется точечная загрузка:

  • только нужные локали
  • только используемые модули (например, без timeZoneNames, если не требуется работа с таймзонами)
  • разделение по чанкам сборщика

Пример стратегии:

  • базовый бандл: en + supplemental
  • дополнительные локали: загружаются динамически

Взаимодействие CLDR и форматтеров Globalize

После загрузки CLDR данные становятся основой для всех форматтеров:

  • Globalize.numberFormatter()
  • Globalize.dateFormatter()
  • Globalize.currencyFormatter()
  • Globalize.plural()

Каждый форматтер обращается к CLDR-структурам во время выполнения, а не на этапе сборки, что обеспечивает гибкость, но требует корректной инициализации данных.


Роль supplemental-данных в кросс-локализации

Supplemental-слой выполняет роль связующего механизма между локалями:

  • унифицирует числовые системы
  • нормализует календарные правила
  • определяет универсальные языковые отношения

Без него main-данные остаются изолированными и не могут корректно взаимодействовать между собой в мультилингвальных сценариях.