Ant Design 的国际化方案

5,851 阅读2分钟
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} />
      )
    }
    

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

    i Light Marina Bay 2017