React前端项目国际化

4,193 阅读2分钟

背景

最近公司项目做国际化,需要至少支持英语和中文两种语言。希望在改动最小的情况下完成任务,尽量避免二次开发。经过调研+实际验证,成功达到目标,写这篇文章记录下我的实现过程。

工具

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是通过编译原理识别底层语法树来做的替换工作,结果较为准备,大大节省了工作量

完整示例