CLDR (Common Locale Data Repository) представляет собой
стандартизированную базу локализационных данных, используемую во
множестве международных библиотек JavaScript через Intl-API
и его полифиллы. В контексте FormatJS именно CLDR определяет поведение
форматирования дат, чисел, относительного времени, правил плюрализации и
множества других языковых особенностей.
FormatJS не хранит эти правила в виде «жёстко зашитой логики». Вместо этого используется набор пакетов, основанных на CLDR-данных, которые подключаются и при необходимости могут быть расширены или переопределены.
В экосистеме FormatJS CLDR используется как источник:
Эти данные инкапсулируются внутри пакетов:
@formatjs/intl-numberformat@formatjs/intl-datetimeformat@formatjs/intl-pluralrules@formatjs/intl-relativetimeformat@formatjs/intl-localeКаждый из них содержит собственный слой CLDR-данных, адаптированный
под Intl-совместимый интерфейс.
Переопределение CLDR-слоя используется в ситуациях, когда:
FormatJS полифиллы предоставляют низкоуровневые методы регистрации локализационных данных. Основной принцип заключается в том, что данные CLDR загружаются явно и добавляются в рантайм через специальные API.
import '@formatjs/intl-numberformat/polyfill';
import '@formatjs/intl-numberformat/locale-data/ru';
Intl.NumberFormat.__addLocaleData(
require('@formatjs/intl-numberformat/locale-data/ru')
);
Здесь происходит загрузка стандартного CLDR-подобного набора данных для чисел и его регистрация в полифилле.
import '@formatjs/intl-datetimeformat/polyfill';
import '@formatjs/intl-datetimeformat/locale-data/ru';
Intl.DateTimeFormat.__addLocaleData(
require('@formatjs/intl-datetimeformat/locale-data/ru')
);
Этот слой управляет форматами:
import '@formatjs/intl-relativetimeformat/polyfill';
import '@formatjs/intl-relativetimeformat/locale-data/ru';
Intl.RelativeTimeFormat.__addLocaleData(
require('@formatjs/intl-relativetimeformat/locale-data/ru')
);
CLDR здесь определяет логику выражений вида:
import '@formatjs/intl-pluralrules/polyfill';
import '@formatjs/intl-pluralrules/locale-data/ru';
Intl.PluralRules.__addLocaleData(
require('@formatjs/intl-pluralrules/locale-data/ru')
);
Именно этот слой критически зависит от CLDR, так как разные языки используют существенно отличающиеся системы множественных форм.
В некоторых сценариях требуется не добавление, а именно замена стандартных данных. Это используется при:
const customLocaleData = {
data: {
// пользовательские правила плюрализации
},
locale: 'ru'
};
Intl.PluralRules.__addLocaleData(customLocaleData);
Такой подход позволяет подменять стандартные CLDR-наборы собственными структурами.
CLDR в FormatJS не загружается автоматически полностью. Вместо этого используется модель явной регистрации:
Это позволяет:
FormatJS позволяет комбинировать CLDR-данные с пользовательскими форматами через ICU Message Syntax. При этом CLDR влияет на низкоуровневую интерпретацию, а сообщения остаются декларативными.
Пример:
{count, plural,
one {# элемент}
few {# элемента}
many {# элементов}
}
Правила выбора формы «one/few/many» определяются именно CLDR-данными, а не самим сообщением.
При конфликте данных действует следующий порядок:
__addLocaleDataIntlТаким образом, любое переопределение полностью перекрывает стандартные значения на уровне конкретной локали.
FormatJS допускает точечное переопределение отдельных компонентов локализации без затрагивания всей локали:
Это достигается установкой отдельных полифиллов и загрузкой соответствующих локальных данных для каждого модуля независимо.
На практике встречаются следующие проблемы:
IntlТакие ситуации приводят к падению форматирования или к возврату к fallback-логике.
CLDR-данные напрямую влияют на:
select,
plural)ICU-сообщения остаются неизменными, но результат их выполнения зависит от активного CLDR-набора.
В случаях, когда локаль отсутствует в стандартном наборе, создаётся собственная запись CLDR-структуры:
ru)Такой подход используется для региональных диалектов или внутренних корпоративных языков интерфейса, где стандартный CLDR не отражает требуемую терминологию и форматирование.