---
createdAt: 2025-11-24
updatedAt: 2025-11-24
title: Компилятор против декларативного i18n
description: Исследование архитектурных компромиссов между «магической» интернационализацией на основе компилятора и явным декларативным управлением контентом.
keywords:
  - Intlayer
  - Интернационализация
  - Блог
  - Next.js
  - JavaScript
  - React
  - i18n
  - Компилятор
  - Декларативный
slugs:
  - blog
  - compiler-vs-declarative-i18n
---

# Аргументы за и против интернационализации на основе компилятора

Если вы разрабатываете веб-приложения более десяти лет, вы знаете, что интернационализация (i18n) всегда была источником сложностей. Это часто та задача, которую никто не хочет выполнять — извлечение строк, управление JSON-файлами и заботы о правилах множественного числа.

В последнее время появилась новая волна инструментов i18n на основе «компилятора», обещающих избавить от этих проблем. Обещание звучит заманчиво: **Просто пишите текст в своих компонентах, а остальное пусть сделает инструмент сборки.** Без ключей, без импортов, просто магия.

Но, как и во всех абстракциях в программной инженерии, магия имеет свою цену.

В этом блоге мы рассмотрим переход от декларативных библиотек к подходам на основе компилятора, скрытые архитектурные долги, которые они вносят, и почему «скучный» способ может оставаться лучшим для профессиональных приложений.

## Краткая история перевода

Чтобы понять, где мы сейчас, нужно оглянуться назад и вспомнить, с чего мы начинали.

Около 2011–2012 годов ландшафт JavaScript был кардинально другим. Такие бандлеры, как мы их знаем сегодня (Webpack, Vite), либо не существовали, либо только зарождались. Мы склеивали скрипты прямо в браузере. В эту эпоху появились библиотеки, такие как **i18next**.

Они решили проблему единственным возможным на тот момент способом: **словарями во время выполнения**. Вы загружали огромный JSON-объект в память, и функция искала ключи на лету. Это было надежно, явно и работало везде.

Перенесемся в настоящее. У нас есть мощные компиляторы (SWC, бандлеры на базе Rust), которые могут парсить абстрактные синтаксические деревья (AST) за миллисекунды. Эта мощь породила новую идею: _Зачем нам вручную управлять ключами? Почему компилятор просто не видит текст "Hello World" и не заменит его за нас?_

Так родился i18n на основе компилятора.

## Привлекательность компилятора (подход "магии")

Есть причина, по которой этот новый подход набирает популярность. Для разработчика опыт кажется невероятным.

### 1. Скорость и "погружение"

Когда вы полностью сосредоточены, остановка, чтобы придумать имя переменной (`home_hero_title_v2`), нарушает ваш поток работы. С подходом компилятора вы просто пишете `<p>Welcome back</p>` и продолжаете. Трения нет.

### 2. Миссия спасения наследия

Представьте, что вы унаследовали огромную кодовую базу с 5000 компонентов и нулевыми переводами. Переделка этого с помощью ручной системы ключей — это кошмар, который может занять месяцы. Инструмент на базе компилятора действует как стратегия спасения, мгновенно извлекая тысячи строк без необходимости вручную трогать ни один файл.

### 3. Эра ИИ

Это современное преимущество, которое не стоит упускать из виду. Ассистенты по написанию кода на базе ИИ (например, Copilot или ChatGPT) естественным образом генерируют стандартный JSX/HTML. Они не знают вашу конкретную схему ключей для перевода.

- **Декларативный:** вам нужно переписать вывод ИИ, чтобы заменить текст на ключи.
- **Компилятор:** вы копируете и вставляете код ИИ, и он просто работает.

## Проверка реальности: почему "магия" опасна

Хотя "магия" привлекательна, абстракция протекает. Полагаться на инструмент сборки, чтобы понять человеческие намерения, вводит архитектурную хрупкость.

### 1. Эвристическая хрупкость (игра в угадайку)

Компилятор должен угадывать, что является контентом, а что — кодом.

- Переводится ли `className="active"`? Это строка.
- Переводится ли `status="pending"`?
- Переводится ли `<MyComponent errorMessage="An error occurred" />`?
- Переводится ли идентификатор продукта, например `"AX-99"`?

В конечном итоге вы неизбежно начинаете "бороться" с компилятором, добавляя специальные комментарии (например, `// ignore-translation`), чтобы предотвратить нарушение логики вашего приложения.

### 2. Жесткое ограничение динамических данных

Извлечение компилятором основано на **статическом анализе**. Он должен видеть буквальную строку в вашем коде, чтобы сгенерировать стабильный ID.
Если ваш API возвращает строку с кодом ошибки, например `server_error`, вы не сможете перевести её с помощью компилятора, потому что компилятор не знает о существовании этой строки во время сборки. Вам придется создавать вторичную систему "только во время выполнения" специально для динамических данных.

### 3. "Взрыв чанков" и сетевые водопады

Для поддержки tree-shaking инструменты компилятора часто разбивают переводы по компонентам.

- **Последствие:** Один просмотр страницы с 50 небольшими компонентами может вызвать **50 отдельных HTTP-запросов** для маленьких фрагментов перевода. Даже с HTTP/2 это создает сетевой "водопад", из-за которого ваше приложение кажется медленным по сравнению с загрузкой одного оптимизированного языкового пакета.

### 4. Нагрузка на производительность во время выполнения

Чтобы сделать переводы реактивными (чтобы они обновлялись мгновенно при переключении языков), компилятор часто внедряет хуки управления состоянием в _каждый_ компонент.

- **Стоимость:** Если вы рендерите список из 5000 элементов, вы инициализируете 5000 хуков `useState` и `useEffect` исключительно для текста. Это потребляет память и ресурсы процессора, которые декларативные библиотеки (которые обычно используют один провайдер Context) экономят.

## Ловушка: Зависимость от поставщика

Это, пожалуй, самый опасный аспект i18n на основе компилятора.

В декларативной библиотеке ваш исходный код содержит явное намерение. Вы владеете ключами. Если вы меняете библиотеку, вы просто меняете импорт.

В подходе на основе компилятора **ваш исходный код — это просто английский текст.** "Логика перевода" существует только внутри конфигурации плагина сборки.
Если эта библиотека перестанет поддерживаться или вы перерастёте её, вы окажетесь в ловушке. Вы не сможете легко "выйти" из неё, потому что в вашем исходном коде нет ни одного ключа перевода. Вам придётся вручную переписать всё приложение, чтобы мигрировать на другую систему.

## Другая сторона: риски декларативного подхода

Честно говоря, традиционный декларативный способ тоже не идеален. У него есть свои "подводные камни".

1.  **Ад namespace:** Часто приходится вручную управлять тем, какие JSON-файлы загружать (`common.json`, `dashboard.json`, `footer.json`). Если вы забудете один из них, пользователь увидит необработанные ключи.
2.  **Перезагрузка:** Без тщательной настройки очень легко случайно загрузить _все_ ключи перевода для _всех_ страниц при первоначальной загрузке, что увеличивает размер вашего бандла.
3.  **Синхронизационный дрейф:** Часто ключи остаются в JSON-файле задолго после того, как компонент, использующий их, был удалён. Ваши файлы перевода растут бесконечно, заполненные "зомби-ключами".

## Средний путь Intlayer

Именно здесь такие инструменты, как **Intlayer**, пытаются внести инновации. Intlayer понимает, что хотя компиляторы мощные, неявная магия опасна.

Intlayer предлагает уникальную команду **`transform`**. Вместо того чтобы просто делать магию на скрытом этапе сборки, она фактически может **переписать ваш код компонента**. Она сканирует ваш текст и заменяет его явными декларациями контента в вашей кодовой базе.

Это даёт вам лучшее из обоих миров:

1.  **Гранулярность:** Вы держите переводы рядом с вашими компонентами (улучшая модульность и tree-shaking).
2.  **Безопасность:** Перевод становится явным кодом, а не скрытой магией на этапе сборки.
3.  **Отсутствие зависимости:** Поскольку код преобразуется в стандартную декларативную структуру внутри вашего репозитория, вы не скрываете логику в плагине webpack.

## Заключение

Итак, что же выбрать?

**Если вы начинающий разработчик, соло-фаундер или создаёте MVP:**
Подход на основе компилятора — это приемлемый выбор. Он позволяет двигаться невероятно быстро. Вам не нужно беспокоиться о структуре файлов или ключах. Вы просто создаёте. Технический долг — это проблема "будущего вас".

**Если вы создаёте профессиональное корпоративное приложение:**
Магия обычно — плохая идея. Вам нужен контроль.

- Вам нужно обрабатывать динамические данные с бэкендов.
- Вам нужно обеспечить производительность на устройствах с низкими характеристиками (избегая взрывов хуков).
- Вам нужно гарантировать, что вы не будете навсегда привязаны к конкретному инструменту сборки.

Для профессиональных приложений **Декларативное управление контентом** (например, Intlayer или проверенные библиотеки) остается золотым стандартом. Оно разделяет ваши задачи, сохраняет архитектуру чистой и гарантирует, что способность вашего приложения поддерживать несколько языков не зависит от "черного ящика" компилятора, который пытается угадать ваши намерения.
