gt-next@6.6.0
概览
在 gt-next 6.6.0 中,我们为对既有(“brown field”)应用进行国际化提供了一种全新的思路。我们引入了 t.obj() 函数,它可以返回已翻译的字典结构。
设计动机
“brownfield”和“greenfield”是从房地产开发领域借用来的术语。greenfield 指的是没有现有建筑物的地块,而 brownfield 则是已有建筑物的地块。在 i18n 语境中,它们分别对应于没有 i18n 基础设施的应用(greenfield)和已经具备 i18n 基础设施的应用(brownfield)。
到目前为止,我们的库一直高度专注于为“greenfield”应用提供国际化支持。比如 <T> 组件或 useGT() hook 就是这样的例子。
我们专门为“brownfield”应用构建的唯一基础设施,是 const t = useTranslations() 和 const t = getTranslations() 这两个 hook,它们参考了 next-intl 的 dictionary 模式。不过,我们的 t() 函数一直存在局限:它只能返回字符串,而不能返回字典的子树。
我们发现,开发者往往希望他们使用的 i18n 库能够返回字典子树,而不仅仅是字符串。因此,当开发者从其他 i18n 库迁移时,gt-next 必须支持这一能力。
用法
来看下面这个字典结构,其中包含你想要遍历的一组条目:
{
"cards": [
{
"title": "卡片1",
"description": "卡片1 description"
},
{
"title": "卡片2",
"description": "卡片2 description"
},
{
"title": "卡片3",
"description": "卡片3 description"
}
]
}在之前的实现中,你需要根据每个条目的精确键名来逐个访问它们:
import { useTranslations } from 'gt-next'
export default function Page() {
const t = useTranslations()
return (
<>
<div>
{t('cards.0.title')}
{t('cards.0.description')}
</div>
<div>
{t('cards.1.title')}
{t('cards.1.description')}
</div>
<div>
{t('cards.2.title')}
{t('cards.2.description')}
</div>
</>
)
}这种方式显然既不具备可扩展性,也不具备可维护性。
新的 t.obj() 函数提供了一种强大的方式,可以将字典结构作为子树来访问:
import { useTranslations } from 'gt-next'
export default function Page() {
const t = useTranslations()
return (
<>
<div>
{t.obj('cards').map((card) => (
<div key={card.title}>
{card.title}
{card.description}
</div>
))}
</div>
</>
)
}结论
t.obj() 函数是在让 gt-next 更好适配全新项目和存量项目方面迈出的重要一步。通过让开发者可以直接操作字典子树,我们消除了对现有应用进行国际化时的一个主要痛点。
这一增强功能让 gt-next 更接近团队对现代 i18n 库所期望的开发体验,使遍历已翻译内容、更轻松地构建更动态、更易维护的国际化应用成为可能。