背景
最近公司项目做国际化,需要至少支持英语和中文两种语言。希望在改动最小的情况下完成任务,尽量避免二次开发。经过调研+实际验证,成功达到目标,写这篇文章记录下我的实现过程。
工具
react-intl
公司项目用的React,因此初始选择的React-intl。这个库提供React组件和API来格式化日期、数字和字符串,还有一些其他的翻译操作。这已经是一个比较成熟且使用量很大的开源库。
使用react-intl做国际化,流程:
1、 在app引入localprovider,注入国际化函数;
2、 把component的中需要翻译的文案用formattedMessage包装,props和state用高阶组件formattedMessage包装,formattedMessage必须有id(唯一)和defaultMessage两个属性
react-intl-universal
由于react-intl使用还需要区分需要翻译的文案是存在于state还是props中,这样不方便使用脚本来扫描识别代码中的文案,并加以包装。因此,调研了另外一个项目react-intl-universal,react-intl-universal的使用要简单得多。
使用步骤
- 1、安装完成后,准备两个json文件 中文 zh.json:
{
"t1": "查看",
"t2": "修改",
"t3": "更新时间:{date}, by"
}
英语 en.json:
{
"t1": "view",
"t2": "modify",
"t3": "Update Time:{date}, by "
}
- 2、生成locale并引入
import intl from 'react-intl-universal';
import EN from '../locale/en.json';
import CH from '../locale/zh.json';
const locales = {
en_US: EN,
zh_CN: CH
};
const language = localStorage.getItem('lang_type') || 'zh_CN';
intl
.init({
warningHandler: (msg, detail) => { //注意该函数开发环境有,打包后就没有了
console.log(`${msg} ${detail}`);
},
currentLocale: language,
locales
})
- 3、文案替换
import intl from 'react-intl-universal';
<button>{intl.get('t1').d('查看')}<button>
<button>{intl.get('t2').d('修改')}<button>
<div>{intl.get('t3', {date: `2019-05-24 16:39:25`})}</div> //带参数
结果展示


效率工具
步骤3可以使用插件完成,推荐工具i18n-ast。其他工具都是使用正则匹配来替换代码中的文案,总是会有一些错漏的情况。但i18n-ast是通过编译原理识别底层语法树来做的替换工作,结果较为准备,大大节省了工作量
完整示例。