国际化所面临的问题
- 语言翻译
- 静态文案翻译(前端静态模板文案)
- 动态文案翻译(server端下发的动态数据)
- 样式
- 不同语言文案长度不一样造成的样式错乱
- 图片的替换
- 第三方服务 依赖库的国际化
- 本地化
- 货币单位
- 货币汇率
- 时间格式
现有的库
// en.js 英文
const en_US = {
'hello': "hello",
'name': 'my name is {name}'
}
export default en_US;
// zh.js 英文
const zh_CN = {
'hello': "你好",
'name': 'my name is {name}'
}
export default zh_CN;
// app.js 导入对应的i18n配置文件
import { addLocaleData, FormattedMessage } from 'react-intl';
import enLocaleData from 'react-intl/locale-data/en';
import zhLocaleData from 'react-intl/locale-data/zh';
import zh from './zh.js';
import en from './en.js';
addLocaleData([...enLocaleData, ...zhLocaleData]);
let lang = 'zh'
<IntlProvider locale={lang} messages={lang === 'zh' ? zh : en}>
<App>
<div></div>
<FormattedMessage id="hello"/>
</App>
</IntlProvider>
优点:React组件化,format多样化。缺点:无法在普通js文件中使用
import intl from 'react-intl-universal';
const locales = {
"en-US": require('./locales/en-US.js'),
"zh-CN": require('./locales/zh-CN.js'),
};
intl.init({
currentLocale: 'en-US', // TODO: determine locale here
locales,
})
.then(() => {
// After loading CLDR locale data, start to render
this.setState({initDone: true});
});
<div>
{intl.get('SIMPLE')}
</div>
优点:react、原生js中可以统一使用函数获取的形形式获取文本
经过取舍后使用该方案
代码批量替换实现
手动替换代码中时间成本太大,使用脚本实现
方案一 实现babel插件,对ast中的中文文本进行处理
方案二 node脚本,正则匹配字符串进行处理
let dictionary = []; // 字典
async function parse(moduleName, filename, context) {
// 处理jsx标签中 中文
let res = await parseStrOfJsx(moduleName, filename, context);
// 处理对象key值中 中文
// 处理引号中 中文
writeFile(moduleName, filename, res)
}
// 读取文件内容
function readFile(moduleName, filename) {
fs.readFile(filename, { encoding: 'utf8' }).then(res => {
parse(moduleName, filename, res);
});
}
// 读取目录中所有js文件
function readPath(moduleName, modulePath) {
glob(modulePath + '/*.?(jsx|js)', null, function(err, files) {
files.forEach(f => readFile(moduleName, f));
});
}
readPath('log', 'E:/cdn_console_v2/cdn_web/src/pages/Log');
- 针对各种字符串进行处理
//普通字符串
let a = '你好'; // let a = intl.get('hello');
let b = "你好"; // let b = intl.get("hello");
// jsx组件中文本
<Select placeholder="选择" /> // <Select placeholder={intl.get('select')} />
<Select placeholder={'选择'} /> // <Select placeholder={intl.get('select')} />
<Select placeholder={"选择"} /> // <Select placeholder={intl.get('select')} />
<View>查看</View> // <View>{intl.get('view')}</View>
// 对象key值,确定是否影响业务代码
{ '你好': '11'} => { [intl.get('hello')]: '11'}
// 需要忽略注释中文
-
匹配出中文文本后,使用google-translate-api翻译成对应的文本(接口可能无效,需使用百度翻译api)
-
替换中文文本为英文key值变量
-
生成对应语言的字典文件
具体实现参照script/auto-translation