不要使用 i18next ❌😢
根据 npmjs.com 统计,i18next 是最受欢迎的 React 国际化库。
这可能是由于名称的选择正确,这让许多开发人员认为 i18next 是 React 和 Next.js 的某种标准库。
在本文中,我将向您展示为什么使用 i18next 意味着搬起石头砸自己的脚。
i18next != i18n
很多开发者对国际化、i18n 和 i18next 这两个术语感到困惑。他们认为 i18n = i18next,所以当有人提到 i18next 时,它就是一种标准。
它不是。
让我澄清一下国际化、i18n 和 i18next 这些词。
国际化是准备您的代码以便能够在不同的语言和文化中运行的过程。
它主要针对不同人类语言的用户渲染不同的文本值。为此,你可以选择任何国际化库。例如,i18next 就是一个不错的选择。
它可以是 React-intl,也可以是 Tolgee JS 或 Lingui。这类库有很多,并没有真正的标准。
i18n只是“国际化”的缩写,因为该词的第一个“i”和最后一个“n”之间恰好省略了 18 个字符。所以,如果你说 i18n,它的意思就是上面描述的国际化过程。
因此,i18next只是可用于国际化的库之一,因此 i18next != i18n。将 i18next 与“React 标准”混淆是错误的,因为 i18next 远非标准。让我们看看原因。
i18next 不使用 ICU 消息格式
国际化问题并不是什么新问题。
它相当古老,几十年来开发人员一直在尝试解决参数插值、复数化、数字格式或日期格式等问题。
当时,有几个项目开发了解决方案,与许多平台合作并定义了我们所谓的标准。
这些标准之一是 Unicode 及其 ICU 消息格式,它解决了所有列出的问题,并且已经为许多主要编程语言实现,例如 JS、PHP、Java、C++、Go、Dart 等。
ICU 消息示例:
{dogsCount, plural, =0 {No dogs} one {One dog is} other {# dogs are}} here.
遗憾的是,i18next 忽略了这个标准,决定自己实现。因此,他们有自己的消息格式、格式化规则和处理复数的方式。
为什么这是一个问题?
一开始,你的项目很小,只有几百个本地化密钥。但随着项目规模扩大,你会拥有多种语言和密钥;为了管理这些,你需要一些本地化平台,例如 Tolgee、Crowdin 或 Phrase。
而这些平台将很难管理特殊消息格式的字符串。
相比之下,在 JS 世界中,像 Tolgee JS、react-intl 或 lingui-js 这样的库遵循 ICU 消息格式,因此大多数本地化平台可以简单地管理这些库的数据。
I18next 功能过多
i18next 是由没有任何本地化经验的开发者创建的。他们为开发者打造了一个很棒的工具,但却包含了一些与本地化无关的功能,因此给翻译人员带来了很多问题。
在我看来,最有问题的是从本地化数据返回数组和对象的支持。
在 i18next 中,您可以执行此操作。
数据:
{
"array": ['a', 'b', 'c']
}
代码:
i18next.t('array', { returnObjects: true });
数组和对象的支持看似简单,它能让你用不同的语言定义不同的数组。然而,当你需要在大多数本地化平台上管理字符串时,这却是一个大问题。
本地化平台设计为基于键值而不是基于结构化对象的基础,因此它们需要能够将此类数据转换为平面键,如array[0]
、array[1]
或array[2]
。
但是,如果用户想要为不同的语言定义不同大小的数组怎么办?这是无法解决的,而且会造成混乱!
此外,数据的使用方式是在代码中决定的,从数据中无法清楚地看出。
因此翻译人员不知道我们是否返回整个数组,或者我们是否使用此路径分别访问键array.0.
同时,我从未遇到过使用数组返回功能进行本地化的好案例。
其他只会造成混乱并且可以省略的功能(例如列表格式化或按上下文选择)对于平台的支持来说并不简单。
看看 Tolgee 🤩
选择一个使用 ICU 消息格式的库是个好主意,例如“linguist or
react-intl”,或者为您的框架选择一个替代方案。
在我的项目中,我使用Tolgee。
这种组合的好处是,我可以始终确保组件兼容,因为它们由同一家公司维护。
它还具有一些非常简洁的功能,例如上下文编辑,这使我能够委托开发人员进行本地化并让产品团队自己管理字符串。
Tolgee JS 使用标准 ICU 消息格式。
Tolgee 是 100% 开源的。
文章来源:https://dev.to/nevodavid/dont-use-i18next-n1a