Table of Content

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} />
  )
}

在其他地方,引入这个工具类,直接用即可。