Сравнение с альтернативными решениями

Библиотека i18next считается одним из наиболее универсальных решений для интернационализации JavaScript-приложений. Она применяется как в браузере, так и на сервере, поддерживает React, Vue, Angular, Node.js, Next.js и десятки дополнительных плагинов. Однако в экосистеме существует множество альтернативных подходов: встроенный API Intl, библиотеки FormatJS, Polyglot.js, LinguiJS, vue-i18n, react-intl и другие.

Сравнение различных решений особенно важно при проектировании крупного приложения, поскольку выбор инструмента влияет на:

  • архитектуру локализации;
  • производительность;
  • масштабируемость;
  • удобство перевода;
  • поддержку pluralization;
  • SSR и SSG;
  • интеграцию с фреймворками;
  • организацию файлов локализации;
  • динамическую загрузку переводов;
  • удобство работы команды переводчиков.

Сравнение i18next и встроенного Intl API

Возможности Intl API

JavaScript содержит встроенный объект Intl, предназначенный для интернационализации:

const formatter = new Intl.DateTimeFormat('ru-RU');

console.log(formatter.format(new Date()));

API поддерживает:

  • форматирование дат;
  • форматирование чисел;
  • валюты;
  • относительное время;
  • plural rules;
  • сортировку;
  • сегментацию текста.

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

const price = new Intl.NumberFormat('de-DE', {
  style: 'currency',
  currency: 'EUR'
});

console.log(price.format(1200));

Ограничения Intl API

Intl не предоставляет:

  • системы переводов;
  • хранения словарей;
  • namespace;
  • fallback-языков;
  • lazy loading переводов;
  • interpolation;
  • backend-интеграций;
  • управления ресурсами локализации.

Пример, который невозможно реализовать только средствами Intl:

t('profile.settings.notifications')

Следовательно, Intl — это низкоуровневый API форматирования, а не полноценная система локализации.


Совместное использование i18next и Intl

На практике i18next часто использует Intl внутри.

Например:

i18next.init({
  interpolation: {
    format(value, format, lng) {
      if (format === 'currency') {
        return new Intl.NumberFormat(lng, {
          style: 'currency',
          currency: 'USD'
        }).format(value);
      }

      return value;
    }
  }
});

Такой подход объединяет:

  • гибкость i18next;
  • стандартизированное форматирование Intl.

Сравнение i18next и react-intl

Архитектура react-intl

Библиотека react-intl входит в экосистему FormatJS.

Пример использования:

<FormattedMessage
  id="welcome"
  defaultMessage="Welcome"
/>

Основная идея react-intl:

  • декларативный React-подход;
  • тесная интеграция с ICU MessageFormat;
  • ориентация исключительно на React.

Преимущества react-intl

ICU MessageFormat из коробки

Поддерживаются сложные plural forms:

<FormattedMessage
  id="messages"
  defaultMessage="{count, plural,
    =0 {No messages}
    one {# message}
    other {# messages}
  }"
  values={{ count }}
/>

Отличная интеграция с React

Система хорошо вписывается в:

  • React Context;
  • hooks;
  • Suspense;
  • SSR.

Недостатки react-intl

Ограниченность экосистемы

react-intl ориентирован исключительно на React. Использование вне React-приложения неудобно.

В отличие от него, i18next работает:

  • в Node.js;
  • в Express;
  • в Electron;
  • в React Native;
  • в Vue;
  • в Angular;
  • в vanilla JavaScript.

Более сложная работа с namespace

В i18next namespace являются центральной частью архитектуры:

t('auth:login')

В react-intl подобная структура реализуется менее удобно.


Меньше возможностей backend-интеграции

Экосистема i18next содержит множество backend-плагинов:

  • HTTP backend;
  • filesystem backend;
  • locize backend;
  • chained backend;
  • CDN integrations.

Когда react-intl предпочтительнее

react-intl хорошо подходит:

  • для чистых React-приложений;
  • при активном использовании ICU;
  • если необходим строгий декларативный стиль.

Когда i18next предпочтительнее

i18next выигрывает:

  • в мультифреймворк-проектах;
  • в enterprise-архитектуре;
  • при SSR;
  • при динамической подгрузке переводов;
  • в микрофронтендах;
  • при сложной структуре namespace.

Сравнение i18next и FormatJS

Особенности FormatJS

FormatJS — это набор инструментов:

  • react-intl;
  • ICU parser;
  • polyfills;
  • message extraction tools.

FormatJS ориентирован на стандарты ECMA-402.


Подход к переводам

FormatJS использует ICU-сообщения:

{
  "cart": "{count, plural, one {# item} other {# items}}"
}

В i18next аналог может выглядеть проще:

{
  "cart_one": "{{count}} item",
  "cart_other": "{{count}} items"
}

Сравнение подходов

Возможность i18next FormatJS
Простота Высокая Средняя
ICU Через плагины Нативно
Framework agnostic Да Частично
Плагины Очень много Ограниченно
Backend ecosystem Развитая Слабее
Learning curve Ниже Выше

ICU против ключевой структуры

ICU мощнее для сложной грамматики:

"{gender, select,
  male {He}
  female {She}
  other {They}
}"

Но сообщения становятся труднее для поддержки.

i18next делает акцент на:

  • простоте;
  • читаемости;
  • модульности;
  • JSON-структуре.

Сравнение i18next и Polyglot.js

Концепция Polyglot.js

Polyglot.js — минималистичная библиотека локализации.

Пример:

polyglot.t('hello');

Преимущества Polyglot.js

Минимализм

Маленький размер библиотеки.

Простота API

Практически отсутствует сложная конфигурация.


Ограничения Polyglot.js

Библиотека не предоставляет:

  • namespace;
  • backend;
  • middleware;
  • lazy loading;
  • SSR-интеграции;
  • rich ecosystem;
  • advanced pluralization;
  • detector plugins.

Разница в масштабировании

Polyglot.js подходит:

  • для небольших проектов;
  • виджетов;
  • простых SPA.

i18next рассчитан на:

  • enterprise-приложения;
  • большие команды;
  • масштабируемые архитектуры.

Сравнение i18next и LinguiJS

Архитектура LinguiJS

LinguiJS сочетает:

  • message extraction;
  • compile step;
  • ICU syntax;
  • React integration.

Сильные стороны LinguiJS

Компиляция переводов

Сообщения компилируются заранее:

lingui compile

Это уменьшает runtime-нагрузку.


Автоматический extraction

<t>Hello</t>

Строки автоматически извлекаются в каталоги.


Ограничения LinguiJS

Более сложный build pipeline

Появляются дополнительные этапы:

  • extraction;
  • compile;
  • sync catalogs.

Меньшая экосистема

По сравнению с i18next:

  • меньше плагинов;
  • меньше backend-решений;
  • меньше интеграций.

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

LinguiJS может выигрывать:

  • в runtime-производительности;
  • в размере итоговых бандлов.

i18next выигрывает:

  • в гибкости;
  • в extensibility;
  • в архитектурных возможностях.

Сравнение i18next и vue-i18n

Назначение vue-i18n

vue-i18n является стандартным решением для Vue.

Пример:

const i18n = createI18n({
  locale: 'ru',
  messages
});

Сильные стороны vue-i18n

Глубокая интеграция с Vue

Поддерживаются:

  • Composition API;
  • SFC;
  • reactive locale switching;
  • directives.

Удобный синтаксис шаблонов

<p>{{ $t('welcome') }}</p>

Ограничения vue-i18n

Главное ограничение — привязка к Vue.

i18next можно использовать:

  • одновременно на backend и frontend;
  • в mixed stack;
  • в microfrontend-архитектуре.

Сравнение i18next и Angular i18n

Подход Angular i18n

Angular содержит встроенную систему локализации.

Пример:

<h1 i18n>Hello</h1>

Особенности Angular i18n

Angular использует:

  • extraction;
  • compile-time translations;
  • build variants.

Преимущества Angular i18n

Высокая производительность

Переводы внедряются на этапе сборки.

Интеграция с Angular CLI

Поддерживается:

  • multiple builds;
  • locale bundles;
  • AOT.

Недостатки Angular i18n

Сложность runtime-переключения языка

Переключение локали часто требует отдельной сборки.


Ограниченная динамичность

Сложнее реализовать:

  • lazy translation loading;
  • remote translations;
  • dynamic namespaces.

Почему i18next часто выбирают даже в Angular

С помощью i18next можно:

  • менять язык без перезагрузки;
  • загружать переводы с сервера;
  • хранить namespace отдельно;
  • обновлять переводы без rebuild.

Сравнение архитектурных подходов

Runtime localization

Подход i18next:

Приложение запускается
↓
Переводы загружаются динамически
↓
Язык переключается runtime

Преимущества:

  • гибкость;
  • динамика;
  • CDN-обновления.

Недостатки:

  • больше runtime-логики.

Compile-time localization

Подход Angular i18n и частично LinguiJS:

Сборка
↓
Встраивание переводов
↓
Готовый locale bundle

Преимущества:

  • производительность;
  • минимальный runtime.

Недостатки:

  • сложность обновлений;
  • необходимость rebuild.

Сравнение экосистем

Экосистема i18next

Наиболее развитая среди JavaScript-решений.

Ключевые модули:

  • i18next-http-backend
  • i18next-browser-languagedetector
  • react-i18next
  • next-i18next
  • i18next-fs-backend
  • i18next-chained-backend

Экосистема FormatJS

Сильна в:

  • ICU;
  • React;
  • стандартах Intl.

Но менее универсальна.


Экосистема LinguiJS

Сосредоточена на:

  • extraction;
  • compile-time localization.

Сравнение подходов к pluralization

i18next

{
  "item_one": "товар",
  "item_few": "товара",
  "item_many": "товаров"
}

Поддерживаются языковые правила CLDR.


ICU-подход

{count, plural,
  one {товар}
  few {товара}
  many {товаров}
}

Практическая разница

ICU:

  • мощнее;
  • компактнее для сложных условий.

i18next:

  • проще для чтения;
  • удобнее для переводчиков;
  • легче поддерживается в JSON.

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

Размер бандла

При базовой конфигурации:

Библиотека Размер
Polyglot.js Очень маленький
i18next Средний
FormatJS Выше среднего
LinguiJS Средний

Runtime-нагрузка

На производительность влияют:

  • interpolation;
  • pluralization;
  • ICU parsing;
  • lazy loading;
  • namespace lookup.

ICU-парсинг обычно тяжелее обычного key lookup.


Масштабируемость

В крупных приложениях i18next показывает преимущества благодаря:

  • namespace;
  • lazy loading;
  • backend abstraction;
  • caching;
  • chained backend architecture.

Сравнение удобства для переводчиков

JSON-структура i18next

{
  "profile": {
    "title": "Профиль"
  }
}

Простая и понятная структура.


ICU-строки

{count, plural, one {# file} other {# files}}

Для неподготовленных переводчиков такой формат сложнее.


Namespace-организация

i18next позволяет разделять переводы:

auth.json
dashboard.json
profile.json

Это особенно важно в enterprise-проектах.


Сравнение поддержки SSR

i18next

Поддерживает:

  • Next.js;
  • Remix;
  • Express SSR;
  • streaming SSR.

react-intl

SSR поддерживается хорошо, но экосистема менее гибкая.


Angular i18n

SSR возможен, но архитектурно менее динамичен.


Сравнение удобства миграции

Переход на i18next

Обычно проще благодаря:

  • plain JSON;
  • framework agnostic API;
  • модульной архитектуре.

Миграция с ICU

Может потребовать:

  • преобразования pluralization;
  • переписывания message syntax;
  • изменения extraction pipeline.

Когда i18next становится лучшим выбором

i18next особенно эффективен при:

  • большом количестве языков;
  • runtime-переключении локалей;
  • SSR;
  • микрофронтендах;
  • сложной структуре приложения;
  • CDN-доставке переводов;
  • shared localization между backend и frontend;
  • multi-platform архитектуре.

Когда альтернативы могут быть лучше

FormatJS / react-intl

Подходят при:

  • глубокой интеграции с React;
  • сложной ICU-грамматике;
  • ориентации на стандарты ECMA-402.

LinguiJS

Полезен при:

  • compile-time optimization;
  • автоматическом extraction;
  • минимизации runtime.

Polyglot.js

Рационален для:

  • небольших приложений;
  • простых SPA;
  • lightweight widgets.

Angular i18n

Эффективен в:

  • монолитных Angular-проектах;
  • compile-time localization;
  • статических production builds.