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 已经支持内联翻译内容,但它仍缺少这类库的两个核心能力:
(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> 组件,用于在不牺牲翻译覆盖率或一致性的前提下,解决句子碎片化问题。