Режимы сборки

@lingo.dev/compiler поддерживает два режима сборки, которые определяют, когда и как генерируются переводы.

Обзор режимов

РежимКогда использоватьAPI-запросыПоведение
translateРазработка, CIДаГенерирует недостающие переводы с помощью настроенного LLM
cache-onlyПродакшн-сборкиНетИспользует только кэшированные переводы из .lingo/metadata.json

Режим translate

Назначение: Генерировать переводы по требованию во время сборки.

{
  buildMode: "translate"
}

Поведение:

  • Сканирует код на наличие переводимого текста
  • Проверяет .lingo/metadata.json на наличие уже существующих переводов
  • Генерирует недостающие переводы через выбранного LLM-провайдера
  • Обновляет .lingo/metadata.json новыми переводами
  • Прерывает сборку, если не удалось сгенерировать перевод

Когда использовать:

  • Локальная разработка (с usePseudotranslator: true)
  • CI/CD пайплайны (с реальными LLM-провайдерами)
  • Первичная настройка и генерация переводов

Требуется:

  • Валидный API-ключ для выбранного провайдера (или включён псевдопереводчик)
  • Сетевое соединение с LLM-провайдером

Режим cache-only

Назначение: Сборка только с уже сгенерированными переводами.

{
  buildMode: "cache-only"
}

Поведение:

  • Читает переводы из .lingo/metadata.json
  • API-запросы не выполняются
  • Прерывает сборку, если отсутствуют переводы для какого-либо языка
  • Быстрая и детерминированная сборка

Когда использовать:

  • Продакшн-сборки
  • Деплой без API-ключей
  • Окружения с ограниченным доступом к сети

Требуется:

  • .lingo/metadata.json с переводами для всех языков
  • Переводы заранее сгенерированы в CI или при разработке

Рекомендуемый рабочий процесс

1. Локальная разработка

Используйте псевдопереводчик для мгновенной обратной связи:

{
  buildMode: "translate",
  dev: {
    usePseudotranslator: true,
  }
}

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

  • Мгновенные фейковые переводы
  • Нет затрат на API
  • Видно, что именно переводится
  • Тестирование UI с разной длиной текста

2. CI/CD pipeline

Генерируйте реальные переводы в CI:

{
  buildMode: "translate",
  dev: {
    usePseudotranslator: false,
  }
}

Настройка в CI:

# GitHub Actions example
- name: Install dependencies
  run: pnpm install

- name: Generate translations
  env:
    LINGODOTDEV_API_KEY: ${{ secrets.LINGODOTDEV_API_KEY }}
  run: pnpm run build

- name: Commit translations
  run: |
    git config user.name "github-actions[bot]"
    git config user.email "github-actions[bot]@users.noreply.github.com"
    git add .lingo/
    git commit -m "chore: update translations" || exit 0
    git push

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

  • Реальные переводы генерируются один раз при каждом деплое
  • Файлы коммитятся в систему контроля версий
  • Для production-сборок не нужны API-ключи

3. Production build

Используются только кэшированные переводы:

{
  buildMode: "cache-only",
}

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

  • Не нужны API-ключи
  • Быстрая сборка
  • Детерминированность — одинаковый ввод всегда даёт одинаковый результат
  • Нет внешних сетевых зависимостей

Переопределение переменной окружения

Переопределите режим сборки через переменную окружения:

# Force cache-only mode
LINGO_BUILD_MODE=cache-only npm run build

# Force translate mode
LINGO_BUILD_MODE=translate npm run build

Это удобно для окружений деплоя, где нужно принудительно включить cache-only без изменения конфигурации.

Обработка отсутствующих переводов

В режиме перевода

Если перевод не удался:

Error: Failed to generate translation for locale "es":
  - Hash: abc123def
  - Source text: "Welcome to our app"
  - Provider: lingo.dev
  - Reason: API key invalid

Решение: Исправьте API-ключ и повторите сборку.

В режиме cache-only

Если переводы отсутствуют:

Error: Missing translations for locale "es":
  - Hash: abc123def
  - Source text: "Welcome to our app"
  - File: app/page.tsx:12

Run with buildMode: "translate" to generate missing translations.

Решение: Запустите сборку в режиме translate, чтобы сгенерировать недостающие переводы, затем закоммитьте .lingo/.

Инкрементальный перевод

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

  1. Каждая переводимая строка получает стабильный хеш
  2. Хеш формируется на основе исходного текста и контекста
  3. Если хеш уже есть в .lingo/metadata.json, перевод используется повторно
  4. Только новый или изменённый текст вызывает повторный перевод

Результат: Вы платите за перевод только один раз. Все последующие сборки используют кэшированные переводы.

Примеры настройки CI

GitHub Actions

name: Generate Translations

on:
  push:
    branches: [main]
  pull_request:

jobs:
  translate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: pnpm/action-setup@v2
        with:
          version: 8

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: "pnpm"

      - name: Install dependencies
        run: pnpm install

      - name: Generate translations
        env:
          LINGODOTDEV_API_KEY: ${{ secrets.LINGODOTDEV_API_KEY }}
        run: pnpm run build

      - name: Commit translations
        if: github.event_name == 'push'
        run: |
          git config user.name "github-actions[bot]"
          git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
          git add .lingo/
          git diff --quiet && git diff --staged --quiet || git commit -m "chore: update translations"
          git push

GitLab CI

stages:
  - translate

generate-translations:
  stage: translate
  script:
    - pnpm install
    - pnpm run build
    - git config user.name "GitLab CI"
    - git config user.email "[email protected]"
    - git add .lingo/
    - git diff --quiet && git diff --staged --quiet || git commit -m "chore: update translations"
    - git push origin HEAD:$CI_COMMIT_REF_NAME
  only:
    - main

Часто задаваемые вопросы

Нужны ли API-ключи в продакшене? Нет. Используйте buildMode: "cache-only" в продакшене. Переводы заранее генерируются в CI.

Что если я забуду сгенерировать переводы в CI? Сборка для продакшена завершится ошибкой с чётким списком недостающих переводов. Сгенерируйте их в CI, закоммитьте и задеплойте заново.

Можно ли использовать translate mode в продакшене? Да, но не рекомендуется. Это делает сборки недетерминированными и требует API-ключи в продакшене. Лучше генерировать переводы в CI.

Как протестировать режим только кэша локально?

  1. Сгенерируйте переводы с помощью translate режима
  2. Переключитесь на cache-only режим
  3. Запустите сборку — она должна пройти, используя кэшированные переводы

Что если мой исходный текст изменится? Хеш изменится, поэтому будет сгенерирован новый перевод (в translate режиме). Старый перевод останется в .lingo/metadata.json для истории.

Нужно ли коммитить .lingo/ в git? Да. Директория .lingo/ должна быть под версионным контролем. В ней хранится ваш кэш переводов.

Дальнейшие шаги