gt-next@6.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.