@exodus/i18n
进入一个更方便的密码世界的网关 对我们所有用户来说,不管他们说什么语言.
使用量
@exodus/i18n 以三大支柱为基础:
- 一套反应组件,一个钩子和一个静态i18n的工厂
- 构建工具,确保这些反应组件成为使用和帮助加载翻译文件的无脑器
- 处理自动取自信件ID的 CLI
<T>财务报告和审定财务报表t援引
反应组件
I18n 提供
在您的组件等级中,包括 I18NProvider它负责提供当前语言
和下游各部分可用的地方.
import { I18nProvider } from '@exodus/i18n'
const I18n = () => {
// ...
return (
<I18nProvider
locale={locale}
locales={locales}
setLocale={setLocale}
currency={currency}
defaultLanguage={DEFAULT_LANGUAGE}
defaultCurrency={DEFAULT_CURRENCY}
>
{children}
</I18nProvider>
)
}
// Where `locales` are created from the PO files:
// locales.js
import en from '~/locales/en/messages.po'
import de from '~/locales/de/messages.po'
export default { en, de }
数字和数字
T 是可直接用于jsx的组件,而 t 是返回已翻译字符串的函数.
import { T, useI18n } from '@exodus/i18n'
const MyComponent = () => (
<Title>
<T>This is a localized message</T>
</Title>
)
const MyOtherComponent = () => {
const { t } = useI18n()
const title = t('Buy all the crypto')
useEffect(() => {
showModal({ title })
}, [title])
return null
}
3⁄4 ̄ ̧漯B 也可以导入
t全球范围,而不是用它与useI18n钩. 全球版本t返回时<T>{arg}</T>而不是翻译输入.
最佳做法
您可以以多种不同的方式使用此库. 见下文最佳做法.
总是在您使用的地方导入 i18n
这个库的CLI依靠进口来检测其使用地点. 如果您不导入 i18n 或指定一个 自定义模块 在配置中,提取可能不正确.
以下例子说明了由于新行不会被逃脱,并将作为实际的新行被收录在PO文件中后如何不做,最终被打破.
// Bad
const BatmobileFuel = ({ t, quantity }) => (
<>
<FuelIcon />
{t(`Fuel Quantity:\n${quantity}`)}
</>
)
如果钩被导入并使用,一切都会如所料.
// Good
import { useI18n } from '@exodus/i18n'
const BatmobileFuel = ({ quantity }) => {
const { t } = useI18n()
return (
<>
<FuelIcon />
{t(`Fuel Quantity:\n${quantity}`)}
</>
)
}
最后,这里有一个例子,显示一个 i18n 配置与自定义模块,输出一个静态 i18n 举个例子.
{
"sourceLocale": "en",
"locales": "src/locales/{locale}/messages.po",
"additionalModules": ["./localization"]
}
// Good with corresponding config
import { t } from './localization'
const getBatmobileFuel = (quantity) => t(`Fuel Quantity:\n${quantity}`)
}
何时使用哪种翻译方法
作为拇指的通则,尽量尽可能地用起钩来. t 财务报告和审定财务报表 T 从库中导出只是连接到钩子周围的通用包装并添加不必要的层.
有些情况下你把JSX嵌入了本地化的绳子 在这种情况下,你想使用 T 因为钩子只支持字符串.
<T>
This is <Highlight>important</Highlight>
</T>
如果你不在反应组件之外 害怕的话 还有工厂的方法, createI18NStatic,允许您创建一个静态的 i18n 实例而不包含上下文.
这不支持在苍蝇上切换地块,而且最有可能需要您重新启动您的应用程序 .
避免条件表达式在 t
有条件的表达,也叫ternary运算符,使得翻译者难以理解要被翻译的信息,并可能在其他语言中产生语法问题.
尝试把这些移动到您的翻译功能的外部 .
// Bad
t(evil ? 'Joker' : 'Batman')
// Good
evil ? t('Joker') : t('Batman')
没有可选的链条 t
目前我们不支持在 t。 。 。 .
// Bad
t(`Joker's real name is ${data.joker?.realName}`)
t(`Batman's health is ${data.joker?.getHealth()}`)
t(`Batman's health is ${batman.getHealth?.()}`)
// Good
const health = batman.getHealth?.()
t(`Batman's health is ${health}`)
使用 Eslint- 插头- i18n
我们提供 Eslint 插件 为上等事. 用电线,卢克!
国 际
国家行动倡议 从您的应用程序中提取消息ID,并在翻译文件中创建相应的条目. 可以用来
电话 i18n extract . 或作为脚本添加到您的 package.json, f.i. 在根包中.json:
{
//...
scripts: {
'i18n:extract': './src/node_modules/.bin/i18n extract ./src',
},
}
提取时忽略文件
您可以使用 ignoreRegex 财产的财产 .i18nrc 配置文件 .
它需要有效的正则表达式和默认值 node_modules|__tests__ 当没有提供时.
{
"sourceLocale": "en",
"locales": "src/locales/{locale}/messages.po",
"ignoreRegex": "node_modules|__tests__|vendor"
}
再出口表达式
为了确保CLI只取出相关的表达式,它会检查导入语句的模块名. 如果你想用另一个模块的i18n 而不是lib本身 并有一个成功的提取, 您必须首先按照以下方法之一调整您的项目.
配置
这个 .i18nrc 配置文件允许您指定 CLI 应另外检查的模块名称
其自名相会. 将您的自定义模块添加到 additionalModules 属性.
{
"sourceLocale": "en",
"locales": "src/locales/{locale}/messages.po",
"additionalModules": ["#/localization"]
}
别名
提供指向自定义模块的别名,以便您可以导入为 @exodus/i18n。 。 。 .
别名设置 :
{
"~": "project-root",
"@exodus/i18n": "./localization.js"
}
localization.js数字 :
export { T } from '~/node_modules/@exodus/i18n'
potter.js数字 :
import { T } from '@exodus/i18n'
const Potter = () => <T>Harry Potter</T>
export default Potter
HOC 和装饰器
这个自由伴随着 withI18n 允许你包好课程组件并获得 t 通过道具.
一种使用方法是通过装饰器.
import { withI18n } from '@exodus/i18n'
class SomeComponent extends React.PureComponent {
render = () => {
const { t } = this.props
return <div title={t('Some String')} />
}
}
export default withI18n(SomeComponent)
如果您想要使用自定义装饰器, 请在 .i18nrc 配置文件 。 否则,i18n将无法正确检测您的翻译并进行转换.
这个 additionalDecorators 属性允许您在 i18n 内置名称之外指定要查找的装饰名称 withI18n。 。 。 .
{
"sourceLocale": "en",
"locales": "src/locales/{locale}/messages.po",
"additionalDecorators": ["withCustomI18n"]
}