gt-next@6.8.0
概览
我们经常发现,代码库越成熟,内容就越分散。
同一句话会被拆成几段,散落在 functions、utilities、业务逻辑和 services 等各个部分。
function getSubject(gender) {
return gender === "male" ? "男孩" : "女孩"
}
function getObject(toy, gender) {
return toy === "球" ? "球" : getSubject(gender)
}
function Component({ gender, toy }) {
return (
<>
<p>
漂亮的{getSubject(gender)}正在玩{getObject(toy, gender)}。
</p>
</>
)
}当应用最终不可避免地走到需要做国际化这一步时,开发者往往会发现自己已经把路走“死”了。 如果不进行大规模重构,就很难在多个文件之间统一处理数的一致、动词变位以及语序变化等问题。 传统做法是,手动提取每个句子的所有可能变体,并将它们逐一添加到翻译字典中。
在 gt-next 6.8.0 中,我们进一步坚定了这样一个理念:一个强大的 i18n 库应该适配现有代码库,而不是反过来。
虽然 gt-next 已经支持内联翻译内容,但它仍然缺少这类库的两个基础特性:
(1) 支持句子拆分,以及 (2) 在保持数的一致、动词变位或语序变化等语言特性不丢失的前提下实现内容复用。
我们引入了 <Static> 组件,使你可以在翻译内部直接调用静态函数。
function getSubject(gender) {
return gender === "male" ? "男孩" : "女孩"
}
function getObject(type, gender) {
return type === "球" ? "球" : getSubject(gender)
}
function Component({ gender, toy }) {
return (
<T>
<p>
漂亮的<Static>{getSubject(gender)}</Static>正在玩<Static>{getObject(toy, gender)}</Static>。
</p>
</T>
)
}重要注意事项
尽管如此,我们仍强烈建议谨慎、合理地使用 <Static> 组件。
<Static> 组件虽然功能强大,但也可能导致翻译条目数量大幅增加。
如果使用不当,这可能会对应用程序的加载时间产生负面影响。
如何使用 <Static>
与 <T> 和 <Var> 组件类似,<Static> 组件是一个标记,用来告诉 CLI 工具哪些地方应该、哪些地方不应该查找可翻译内容。
它会指示 CLI 工具对 <Static> 标签内的函数调用进行解引用,并将该函数可能返回的所有内容都收集进翻译目录。
把每一个 return 语句都当作是被 <T> 组件包裹了一样来处理。
当 CLI 工具找到某个函数调用的所有可能输出后,它会为每一种可能的输出创建一个单独的翻译条目。 例如,下面的代码会创建两个不同的翻译条目:"The boy is beautiful" 和 "The girl is beautiful"。 由于每种可能的输出都有单独的翻译条目,我们就可以在一个被拆分的句子中支持性数配合、动词变位和词序,比如:"El niño es hermoso" 和 "La niña es hermosa"。
function getSubject(gender) {
return gender === "male" ? "boy" : "girl"
}
function Component({ gender }) {
return (
<T>
这个<Static>{getSubject(gender)}</Static>很漂亮。
</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> 玩 <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 "男孩"
} else if (condition2) {
return 22
} else {
return true
}
case "jsx expressions":
return (
<>
你好,<Static>{getTitle(title)}</Static>。<Var>{name}</Var>,你好吗?
</>
);
case "ternary operators":
return condition ? "男孩" : "女孩"
case "function calls":
return otherStaticFunction();
}
}结论
gt-next 6.8.0 引入了 <Static> 组件,在不牺牲翻译覆盖范围或正确语法一致性的前提下,为解决句子碎片化问题提供了方案。