Назад

gt-next@6.3.0

Ernest McCarter avatarErnest McCarter
gt-next6.3.0Разработка с ИИПеревод строк

Обзор

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

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


Сравнение

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

export const greeting1 = 'Hello, world!'
export const getGreeting2 = (gt: any) => gt('Hello, world!')
import { greeting1, getGreeting2 } from './constants'

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

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

export const greeting1 = 'Hello, world!'
export const greeting2 = msg('Hello, world!')
import { greeting1, greeting2 } from './constants'

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

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

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

<interpolated content>:<base64 encoded string>

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

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

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

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

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

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

Пример

Исходный код без i18n:

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

if (message.length > 10) {
  console.log('The message is too long')
} else {
  console.log('The message is just the right length')
}

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

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

const name = 'John'
const message = msg('Hello, {name}!', { name })

if (decodeMsg(message).length > 10) {
  console.log('The message is too long')
} else {
  console.log('The message is just the right length')
}

Другое

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

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

const message = msg('Hello, {name}!', { name: 'John' })

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

Сводка

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