gt-next@6.3.0
Обзор
В 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.