Ant Design 的国际化方案
Ant Design 官方的文档好像没更新,反正是用起来没配成功,官方的文档和代码也是互相矛盾,我来介绍下我是怎么做国际化的。
Antd 的国际化依赖于 yahoo/react-intl。
在看这篇文章之前,建议大家看看 antd/antd-mobile 国际化方案。这篇文章并不是一个 Start Guidelines。
文件目录如下
- src/locales 里面放国际化相关资源
- l10n.config.js 是配置文件
├── l10n.config.js
├── node_modules
├── package.json
└── src
├── index.html
├── index.js
├── locales
└── utils
src/locales 目录我们新建一个 en-US.js
,内容为
import antdEn from 'antd/lib/locale-provider/en_US'
import appLocaleData from 'react-intl/locale-data/en'
import enMessages from './en.json'
export default {
messages: {
...enMessages,
},
antd: antdEn,
locale: 'en-US',
data: appLocaleData,
}
在 index.js 里面我们引入该文件
import enUS from 'locales/en-US'
官方给的 demo,直接把 enUS 赋值给了 window.appLocale,这样做感觉不合理,我的做法是
const getCurrentAppLocale = () => {
const language = store.get('language_key')
switch (language) {
case 'zh-Hans-CN':
return zhCN
default:
return enUS
}
}
window.appLocale = getCurrentAppLocale()
ReactDOM.render(
<IntlProvider
locale={window.appLocale.locale}
messages={window.appLocale.messages}
formats={window.appLocale.formats}
>
<App />
</IntlProvider>,
document.getElementById('root')
)
只需要在切换语言的时候,把 language_key
存到 store
,然后刷新页面。
关于国际化资源的做法,有两种,一种是官方做法,第二种是我的做法。
官方做法:
在 package.json
里面的 scripts
加一条
"trans": "atool-l10n",
需要国际化的地方使用
<FormattedMessage id='key' defaultMessage='message' />
然后执行
npm run trans
他会遍历所有的 FormattedMessage,全部存到 en.json,这个过程有一个 bug,如果你默认语言是 en,他是不会自动生成 zh.json 的,如果默认语言是 zh,他会调用有道词典的 API,自动生成 en.json 并翻译。
需要提醒的是,之后生成的
l10n.config.js
并不是那么的好用,我们还要做些修改
具体的参数看这里ant-tool/atool-l10n
我的参数为
module.exports = {
"middlewares": {
"summary": [
"summary?sourcePattern=build/messages/**/*.json"
],
"process": [
"fetchLocal?source=locales,skip",
"metaToResult?from=defaultMessage,to=en",
"youdao?apiname=YourName,apikey=YourKey",
"reduce?-autoPick,autoReduce[]=local,autoReduce[]=meta"
],
"emit": [
"save?dest=src/locales"
]
}
}
我的做法:
既然默认语言为英文的情况下不好用,自动生成 .json 的时候也有一定可能搞乱顺序,讲真,这个工具确实不是那么的可靠...
干脆人肉翻译了,之前做 iOS 的时候,也是要在每种语言的资源下,先添加对应 key value,再在程序中使用。再顺便构造出一个工具类,传入 id,返回标签。
FormattedMessage 的 defaultMessage 不能动态传入,必须是一个确定值,不过既然决定不用官方的 atool-l10n,也就无所谓啦。
import React from 'react'
import { FormattedMessage } from 'react-intl'
export default function (msgID) {
return (
<FormattedMessage id={msgID} />
)
}
在其他地方,引入这个工具类,直接用即可。