Intl.ListFormat polyfill из экосистемы FormatJS обеспечивает воспроизведение стандарта ECMAScript Internationalization API в средах, где нативная реализация отсутствует или работает неполно. Основная цель — унифицировать форматирование списков (перечислений) в разных локалях с учётом грамматических правил языка, а не просто склеивать элементы через запятую или союз.
Стандартный Intl.ListFormat позволяет формировать
корректные списки элементов с учётом языка и контекста:
Проблема заключается в том, что не все среды исполнения JavaScript имеют полноценную реализацию этого API. Полифилл из FormatJS закрывает этот пробел, предоставляя одинаковое поведение в браузерах и Node.js.
Библиотека поставляется как часть пакета
@formatjs/intl-listformat.
npm install @formatjs/intl-listformat
Подключение полифилла выполняется до использования
Intl.ListFormat:
import '@formatjs/intl-listformat/polyfill';
import '@formatjs/intl-listformat/locale-data/ru';
Для приложений, работающих с несколькими локалями, подключаются соответствующие наборы данных:
import '@formatjs/intl-listformat/locale-data/en';
import '@formatjs/intl-listformat/locale-data/de';
import '@formatjs/intl-listformat/locale-data/ru';
Такой подход позволяет минимизировать размер бандла, загружая только необходимые локали.
После подключения полифилла API полностью повторяет стандартный
Intl.ListFormat:
const formatter = new Intl.ListFormat('ru', {
style: 'long',
type: 'conjunction'
});
formatter.format(['яблоки', 'груши', 'сливы']);
// "яблоки, груши и сливы"
Разные типы списков:
const disjunction = new Intl.ListFormat('ru', {
type: 'disjunction'
});
disjunction.format(['яблоки', 'груши', 'сливы']);
// "яблоки, груши или сливы"
const unit = new Intl.ListFormat('en', {
type: 'unit'
});
unit.format(['5 ft', '10 in']);
// "5 ft, 10 in"
Intl.ListFormat принимает два основных параметра
конфигурации: locale и options.
Определяет язык форматирования:
new Intl.ListFormat('ru');
new Intl.ListFormat('en-US');
new Intl.ListFormat('fr');
Если локаль не поддерживается напрямую, активируется fallback-цепочка, определяемая ICU-данными внутри полифилла.
Определяет степень формальности и формат вывода:
long — полный вариант («A, B и C»)short — сокращённый вариант («A, B & C»)narrow — максимально компактный форматnew Intl.ListFormat('en', { style: 'short' });
Определяет семантику списка:
conjunction — логическое «и»disjunction — логическое «или»unit — единицы измерения или однородные элементыФорматирование списков строго зависит от языковых правил.
new Intl.ListFormat('ru', { type: 'conjunction' })
.format(['HTML', 'CSS', 'JavaScript']);
Результат:
HTML, CSS и JavaScript
new Intl.ListFormat('en', { type: 'conjunction' })
.format(['HTML', 'CSS', 'JavaScript']);
HTML, CSS, and JavaScript
new Intl.ListFormat('de', { type: 'disjunction' })
.format(['A', 'B', 'C']);
A, B oder C
FormatJS использует набор CLDR-данных (Unicode Common Locale Data Repository), из которых извлекаются правила построения списков. Эти правила включают:
Полифилл фактически эмулирует поведение ICU, применяя заранее подготовленные шаблоны.
Простейшая реализация без Intl:
function formatList(arr) {
return arr.slice(0, -1).join(', ') + ' и ' + arr[arr.length - 1];
}
Проблемы такого подхода:
Intl.ListFormat решает эти проблемы за счёт декларативного API.
Поведение стандартизировано:
new Intl.ListFormat('ru').format([]);
// ""
new Intl.ListFormat('ru').format(['A']);
// "A"
Для двух элементов используются специальные шаблоны локали, а не общий алгоритм склеивания.
В приложениях, использующих FormatJS как основу интернационализации,
Intl.ListFormat часто применяется совместно с:
react-intl@formatjs/intl-pluralrules@formatjs/intl-displaynamesПример в компоненте:
const formatter = new Intl.ListFormat(locale, {
type: 'conjunction'
});
const text = formatter.format(items);
Важно учитывать, что форматтер лучше создавать вне рендера или мемоизировать, чтобы избежать лишних вычислений.
Полифилл может увеличивать размер приложения за счёт локальных данных. Оптимизация достигается через:
import '@formatjs/intl-listformat/locale-data/ru';
В больших приложениях часто используется динамическая подгрузка локалей при смене языка.
В серверных средах поведение зависит от версии Node.js. Если нативная поддержка отсутствует или неполная, полифилл гарантирует консистентный результат между сервером и клиентом.
Типичная схема:
import '@formatjs/intl-listformat/polyfill';
import '@formatjs/intl-listformat/locale-data/ru';
Это предотвращает гидрационные ошибки, связанные с различиями форматирования на сервере и в браузере.
Несмотря на высокую совместимость, существуют ограничения:
Тем не менее поведение остаётся стабильным и предсказуемым, что критично для интернационализированных интерфейсов.
Intl.ListFormat особенно полезен в интерфейсах, где списки формируются динамически:
В таких случаях важна не просто читаемость, а грамматическая корректность в конкретной локали, которую невозможно надёжно реализовать вручную без дублирования логики.