通知:现在出来了比较新的库:i18next,具体实践可以看这篇文章:juejin.cn/post/720473…
其实国际化就是:根据当前选择的语言,将应用中的静态文本切换成对应的语言。
这里主要需要两个信息
- 选择的语言:可以是跟随系统的,也可以是自己定义的
- 语言包:k-v存储的内容,k是这个内容的键,v是显示的内容
在开发中,大部分情况都是一开始没有做国际化,后来业务扩展业务到国外,需要英文版的应用,这个时候如果要手工一个个文本替换,工作量未免太大。
不会偷懒的程序员不是好程序员😏,现在肯定有工具可以解决的,然后还真发现了一个,di18n。
大概的原理就是转AST,替换文本,再转回来,有兴趣的可以自行查阅。

总结一下,需要用到的库
- 获取系统的语言:react-native-localize
- js多语言配置:i18n-js
- 文本自动转换工具:di18n
实战部分
新建项目
新建一个rn项目
npx react-native init i18n_practice
安装第三方库
把上文提到的第三方库都安装一下
yarn add react-native-localize i18n-js
yarn add -D di18n-cli
生成国际化语言包和配置
初始化
npx di18n init
初始化完成后会生成一些东西
一个是语言包
一个是配置文件
这里默认的入口是src,rn官方默认的模板没有,所以创建一个src目录把App.js挪进去
另外,配置文件还要做一些修改
module.exports = {
entry: ['src'],
exclude: [],
output: ['src'],
disableAutoTranslate: true,
extractOnly: false,
translator: null,
ignoreComponents: [],
ignoreMethods: [],
primaryLocale: 'zh-CN',
supportedLocales: ['zh-CN', 'en-US'],
- importCode: "import { intl } from 'di18n-react';",
- i18nObject: 'intl',
+ importCode: "import I18n from 'i18n-js';", // 使用i18n-js库
+ i18nObject: 'I18n', // 和上面import的变量保持一致
i18nMethod: 't',
prettier: {singleQuote: true, trailingComma: 'es5', endOfLine: 'lf'},
localeConf: {type: 'file', folder: 'locales'},
};
测试了一下,现在不支持主语言是英语的转换❗️
所以我们要先修改一下APP.js,加入一些中文
转换源代码
现在,运行转换命令
npx di18n sync
然后会发现App.js的内容改变了
- 在上面导入了
importCode属性对应的变量
- 将中文使用
I18n.t包裹起来
语言包也更新了,中文英文是一样的,需要自己修改
修改一下英文语言包
然后发现内容变成了这样
原因是没有修改I18n的配置,默认的配置无法找到语言包
加入配置文件
新建config/i18n.js
/**
* 多语言配置文件
*/
import I18n from 'i18n-js';
import * as RNLocalize from 'react-native-localize';
import en from '../locales/en-US';
import zh from '../locales/zh-CN';
// 获取手机本地国际化信息
const locales = RNLocalize.getLocales();
const systemLanguage = locales[0]?.languageCode; // 用户系统偏好语言
I18n.fallbacks = true;
// 加载语言包
I18n.translations = {
zh,
en,
};
if (systemLanguage) {
I18n.locale = systemLanguage;
} else {
I18n.locale = 'en';
}
export default I18n;
然后就没问题了

App内切换语言
如果在app内切换语言,需要以app内的语言为准,切换完成要重新刷新js内容才会生效,然后要将用户选择的语言进行持久化存储。
加入两个第三方库
- react-native-restart:刷新app bundle
- async-storage:持久化存储
yarn add react-native-restart @react-native-community/async-storage
修改配置文件config/i18n.js,加入修改语言和重置方法
/**
* 多语言配置文件
*/
import I18n from 'i18n-js';
import * as RNLocalize from 'react-native-localize';
import en from '../locales/en-US';
import zh from '../locales/zh-CN';
import AsyncStorage from '@react-native-community/async-storage';
import RNRestart from 'react-native-restart';
// 获取手机本地国际化信息
const locales = RNLocalize.getLocales();
const systemLanguage = locales[0]?.languageCode; // 用户系统偏好语言
export const languageKey = 'language';
I18n.fallbacks = true;
// 加载语言包
I18n.translations = {
zh,
en,
};
/**
* 初始化
*/
AsyncStorage.getItem(languageKey).then(value => {
if (value) {
I18n.locale = value;
} else if (systemLanguage) {
I18n.locale = systemLanguage;
} else {
I18n.locale = 'en';
}
});
/**
* 修改语言
* @param {*} language 语言
*/
export async function changeLanguage(language) {
await AsyncStorage.setItem(languageKey, language);
// Immediately reload the React Native Bundle
RNRestart?.Restart();
}
/**
* 重置
*/
export async function resetLanguage() {
await AsyncStorage.removeItem(languageKey);
// Immediately reload the React Native Bundle
RNRestart?.Restart();
}
export default I18n;
在app.js中加入测试代码
测试
ok,多语言切换功能完成👏
完整代码地址:gitee.com/wcly/i18n_p…