Интернационализация в JavaScript в современном вебе опирается на встроенный стандарт ECMAScript Internationalization API (Intl), который предоставляет единый механизм форматирования дат, чисел, валют, единиц измерения и текстовых конструкций с учётом локали. В экосистеме Angular эта функциональность используется как на уровне платформы, так и через шаблонные инструменты и DI-механизмы, формируя связку между стандартным API браузера и фреймворком интернационализации.
Angular строит свою i18n-модель поверх двух уровней: compile-time интернационализации шаблонов и runtime-форматирования через JavaScript Intl API. Такое разделение позволяет одновременно оптимизировать производительность и обеспечить точность локализованного вывода.
ECMAScript Internationalization API предоставляет набор объектов-конструкторов:
Каждый объект принимает локаль и параметры форматирования:
const formatter = new Intl.NumberFormat('ru-RU', {
style: 'currency',
currency: 'RUB'
});
formatter.format(12345.67);
Результат зависит от локали среды выполнения, что делает Intl API фундаментом для Angular pipe-инструментов.
Angular предоставляет встроенные пайпы для локализации:
Эти пайпы используют Intl API в современных браузерах, а в некоторых случаях fallback-реализацию для старых окружений.
Пример DatePipe:
{{ today | date:'longDate' }}
Под капотом формируется объект Intl.DateTimeFormat с соответствующими параметрами локали.
Эквивалент на чистом Intl API:
new Intl.DateTimeFormat('ru-RU', {
dateStyle: 'long'
}).format(new Date());
Angular абстрагирует создание formatter-объектов, управляет кешированием и реактивностью изменений локали.
В Angular локаль определяется через токен DI:
import { LOCALE_ID } from '@angular/core';
providers: [
{ provide: LOCALE_ID, useValue: 'ru' }
]
Эта настройка влияет на:
Intl API получает локаль либо напрямую, либо через Angular wrapper:
new Intl.NumberFormat('ru').format(1000);
При смене LOCALE_ID Angular пересоздаёт форматтеры, что приводит к изменению представления данных без изменения бизнес-логики.
Angular использует ICU Message Format для сложных языковых конструкций:
{itemsCount, plural,
=0 {нет элементов}
one {1 элемент}
few {# элемента}
many {# элементов}
}
Подобная логика частично пересекается с Intl.PluralRules:
new Intl.PluralRules('ru-RU').select(5);
Возвращаемое значение (one, few,
many) используется для выбора правильной формы.
Angular компилирует ICU выражения на этапе сборки, превращая их в эффективные JS-конструкции, минимизируя runtime-накладные расходы.
Числовая локализация в Angular часто соответствует Intl.NumberFormat:
const nf = new Intl.NumberFormat('de-DE', {
minimumFractionDigits: 2
});
nf.format(1234.5);
В Angular эквивалент:
{{ 1234.5 | number:'1.2-2' }}
Параметры пайпа интерпретируются и транслируются в настройки Intl:
1.2-2 → минимальное и максимальное количество
знаковОсобенности:
1,234.5 vs
1.234,5)Форматирование валюты напрямую связано с Intl.NumberFormat:
new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD'
}).format(99.99);
Angular:
{{ 99.99 | currency:'USD' }}
Внутренние механизмы:
Особенно важен режим display:
currencyDisplay: 'symbol' | 'code' | 'name'
Intl API:
new Intl.DateTimeFormat('fr-FR', {
dateStyle: 'full',
timeStyle: 'short'
}).format(new Date());
Angular:
{{ now | date:'full' }}
Сравнение поведения:
yyyy-MM-dd)long,
short, full)В современных браузерах Angular старается делегировать форматирование Intl API для снижения сложности реализации.
Списки часто требуют языковой корректности:
new Intl.ListFormat('en-GB', {
style: 'long',
type: 'conjunction'
}).format(['apples', 'bananas', 'oranges']);
Результат:
apples, bananas and oranges
В Angular это не всегда вынесено в отдельный pipe, но используется при построении UI-компонентов, особенно в:
Сортировка зависит от локали:
['ä', 'a', 'z'].sort(
new Intl.Collator('de').compare
);
В Angular это важно для:
Без Intl.Collator сортировка происходит по Unicode code points, что приводит к некорректному порядку в локализованных интерфейсах.
Angular разделяет интернационализацию на два слоя:
Такое разделение позволяет:
Intl API опирается на данные окружения:
navigator.language
Angular может использовать:
SSR особенно чувствителен к различиям между окружениями:
Создание Intl объектов дорогостоящее:
new Intl.NumberFormat('ru-RU');
Angular применяет стратегии:
Это особенно критично для:
Некоторые окружения требуют polyfill Intl API:
Angular CLI может подключать:
@angular/localizeintl polyfillsВажно учитывать, что неполный ICU dataset в Node.js влияет на доступные локали и корректность форматирования.
Множественность в языках не ограничивается английским
one/many.
new Intl.PluralRules('ru-RU').select(3);
Результат может быть:
onefewmanyotherAngular ICU синтаксис напрямую отображает эти категории, обеспечивая точную грамматическую адаптацию текста.
Современный Intl API поддерживает форматирование единиц:
new Intl.NumberFormat('ru-RU', {
style: 'unit',
unit: 'kilometer'
}).format(5);
Это используется в Angular приложениях для:
Angular предоставляет декларативные механизмы через шаблоны, тогда как Intl API остаётся императивным инструментом:
Такое разделение упрощает архитектуру: