Назад

gt-next@6.3.0

Ernest McCarter avatarErnest McCarter
gt-next6.3.0AI DevelopmentString translation

Обзор

В gt-next 6.3.0 мы приближаемся к библиотеке, которая одинаково удобна и для разработчиков-людей, и для разработчиков‑ИИ. Нашим основным принципом в этом релизе было свести изменения в существующем коде к минимуму, при этом добавив необходимую функциональность для i18n.

Для этого мы представляем новую функцию msg() для перевода строк в любом месте вашего кода. Ранее разработчикам приходилось прокидывать функцию t() из useGT() или getGT() вверх по стеку вызовов, чтобы перевести строку. С msg() вы просто один раз оборачиваете строку, а затем пропускаете её через m() на этапе рендеринга.


Сравнение

Раньше строки приходилось оборачивать, пробрасывая функцию t() через несколько уровней:

export const greeting1 = 'Привет, мир!'
export const getGreeting2 = (t: any) => t('Привет, мир!')
import { greeting1, getGreeting2 } from './constants'

export default function Page() {
  const t = useGT()
  return (
    <div>
      {greeting1}
      {getGreeting2(t)}
    </div>
  )
}

Теперь с msg() строки можно объявлять напрямую как константы. Единственное требование — при отображении пропускать их через m() (из useMessages() или getMessages()).

export const greeting1 = 'Привет, мир!'
export const greeting2 = msg('Привет, мир!')
import { greeting1, greeting2 } from './constants'

export default function Page() {
  const m = useMessages()
  return (
    <div>
      {greeting1}
      {m(greeting2)}
    </div>
  )
}

Кодирование и декодирование

Чтобы поддерживать интерполяцию, функция msg() возвращает закодированное сообщение вместо обычной строки. Формат выглядит так:

<интерполированный контент>:<строка в кодировке base64>

Часть, закодированная в base64, содержит JSON-объект со следующими данными:

  • $_hash: хеш исходной строки
  • $_source: параметры, подставленные в сообщение
  • $id: пользовательский уникальный идентификатор (если указан)
  • $context: контекст сообщения (если задан)
  • Любые переменные, использованные при интерполяции

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

Почему используется закодированная строка?

Альтернатива использованию закодированной строки заключалась бы в том, что msg() должен был бы возвращать объект пользовательского типа, содержащий дополнительные метаданные. Хотя это подходит для парадигмы кодирования/декодирования, при строгой типизации возникают проблемы.

Мы пришли к выводу, что наилучший способ минимизировать влияние i18n в этом сценарии — просто возвращать строку, внутри которой содержатся метаданные.

Пример

Оригинальный код без i18n:

const name = 'John'
const message = `Hello, ${name}!`

if (message.length > 10) {
  console.log('Сообщение слишком длинное')
} else {
  console.log('Длина сообщения оптимальна')
}

С помощью msg() и decodeMsg():

import { msg, decodeMsg } from 'gt-next'

const name = 'John'
const message = msg('Привет, {name}!', { name })

if (decodeMsg(message).length > 10) {
  console.log('Сообщение слишком длинное')
} else {
  console.log('Сообщение подходящей длины')
}

Другое

Вы также можете переопределять параметры внутри функции t(), даже если они уже были подставлены при вызове msg().

import { msg, useMessages } from 'gt-next'

const message = msg('Привет, {name}!', { name: 'John' })

export default function Page() {
  const m = useMessages()
  return <div>{m(message, { name: 'Jane' })}</div> // Вернёт "Привет, Jane!"
}

Краткое описание

В этом релизе основной упор сделан на повышение удобства работы с gt-next для разработчиков при одновременном снижении накладных расходов на i18n. Благодаря тому, что больше не нужно передавать функцию t() по стеку вызовов, новая функция msg() предоставляет более чистый и интуитивно понятный способ перевода строк и значительно упрощает процесс i18n.