gt-next@6.8.0
Обзор
Чем зрелее кодовая база, тем чаще контент оказывается фрагментированным. Предложения оказываются разбросаны по функциям, утилитам, логике и сервисам.
function getSubject(gender) {
return gender === "male" ? "boy" : "girl"
}
function getObject(toy, gender) {
return toy === "ball" ? "ball" : getSubject(gender)
}
function Component({ gender, toy }) {
return (
<>
<p>
The beautiful {getSubject(gender)} plays with the {getObject(toy, gender)}.
</p>
</>
)
}Когда неизбежно приходит время интернационализации, разработчики понимают, что загнали себя в угол. Без серьёзного рефакторинга становится невозможно поддерживать согласование, спряжение и изменения порядка слов в нескольких файлах. Традиционно для этого приходилось вручную извлекать все возможные варианты каждой фразы и добавлять их в словарь переводов.
В gt-next 6.8.0 мы ещё увереннее придерживаемся идеи, что мощная библиотека i18n должна адаптироваться к кодовой базе, а не наоборот.
Хотя gt-next уже переводит контент inline, ей по-прежнему не хватает двух ключевых возможностей такой библиотеки:
(1) поддержки фрагментации предложений и (2) повторного использования контента с сохранением согласования, спряжения и изменений порядка слов.
Мы представляем компонент <Static>, который позволяет использовать статические вызовы функций прямо внутри переводов.
function getSubject(gender) {
return gender === "male" ? "boy" : "girl"
}
function getObject(type, gender) {
return type === "ball" ? "ball" : getSubject(gender)
}
function Component({ gender, toy }) {
return (
<T>
<p>
The beautiful <Static>{getSubject(gender)}</Static> plays with the <Static>{getObject(toy, gender)}</Static>.
</p>
</T>
)
}Важные замечания
Тем не менее мы настоятельно рекомендуем использовать компонент <Static> осторожно и только там, где это действительно оправданно.
Компонент <Static>, хотя и очень мощный, может значительно увеличить количество записей перевода.
При неправильном использовании это может негативно повлиять на время загрузки приложения.
Как использовать <Static>
Как и компоненты <T> и <Var>, компонент <Static> служит маркером, который указывает CLI-инструменту, где искать переводимый контент, а где — нет.
Он сообщает CLI-инструменту, что нужно разыменовать вызов функции внутри тегов <Static> и занести в каталог все возможные значения, которые возвращает эта функция.
Рассматривайте каждый оператор return так, как если бы он был обёрнут в компонент <T>.
Когда CLI-инструмент находит все возможные результаты вызова функции, он создаёт отдельную запись перевода для каждого из них. Например, следующий код создаёт две отдельные записи перевода: "Мальчик красивый" и "Девочка красивая". Поскольку для каждого возможного результата создаётся отдельная запись перевода, можно поддерживать согласование, спряжение и порядок слов во фрагментированном предложении: "El niño es hermoso" и "La niña es hermosa".
function getSubject(gender) {
return gender === "male" ? "boy" : "girl"
}
function Component({ gender }) {
return (
<T>
The <Static>{getSubject(gender)}</Static> is beautiful.
</T>
)
}Ограничения и планы по улучшению
Умножение
Как уже упоминалось, компонент <Static>, если использовать его слишком часто, может создавать большое количество записей перевода, что может негативно влиять на производительность и время загрузки.
Например, рассмотрим компонент с двумя компонентами <Static>, каждый из которых оборачивает вызов функции с двумя возможными результатами.
В этом случае создаются четыре записи перевода.
Каждый дополнительный компонент <Static> умножает количество переводов на число возможных результатов каждого вызова функции.
function getSubject(gender) {
return gender === "male" ? "boy" : "girl"
}
function getObject(toy) {
return toy === "ball" ? "ball" : "crayon"
}
function Component({ gender, toy }) {
return (
<T>
<Static>{getSubject(gender)}</Static> plays with the <Static>{getObject(toy)}</Static>.
</T>
)
}Синтаксис
Важно рассматривать каждый оператор return так, как будто он обёрнут в компонент <T>.
Любые переменные или вызовы функций с динамическими значениями по-прежнему должны быть обёрнуты в компоненты <Var>.
Сейчас <Static> поддерживает в качестве дочерних элементов только вызовы функций, но в будущем сможет поддерживать и более сложные выражения.
Начиная с gt-next 6.8.0, для статических функций поддерживается следующий синтаксис:
function getExamples(key) {
switch (key) {
case "string, number, and boolean literals":
if (condition1) {
return "The boy"
} else if (condition2) {
return 22
} else {
return true
}
case "jsx expressions":
return (
<>
Hello, <Static>{getTitle(title)}</Static>. How are you, <Var>{name}</Var>?
</>
);
case "ternary operators":
return condition ? "The boy" : "The girl"
case "function calls":
return otherStaticFunction();
}
}Заключение
gt-next 6.8.0 представляет компонент <Static> как решение проблемы фрагментации предложений без ущерба для полноты перевода и корректного грамматического согласования.