前言目前有很多项目涉及国际化以支持多语言环境。例如:在React和Vue这两个最流行的框架中,最常用的两个UI库:AntDesign和Element都实现了国际化需求。而且实现方式也没有太大区别,都是通过缓存对象的语言环境,然后读取对应的语言文件。eg:zh-cn.js、en.js……(当然还有zh-cn.json、en.json)。如何使用可以参考官网。使用国际化的不便虽然国际化看起来实现起来比较简单(当然是比较简单)。但是在实际项目中,还是有比较麻烦的地方。顿时觉得又增加了很多要求。添加一句话可能需要更改多个文件。产品总监顿时后悔了,运营总监觉得翻译的不顺畅。怎么回事,换个翻译文件吧。。。这种情况怎么解决?推荐一个简单的翻译系统,代码阶段只需要实现一两个语言环境。其他的,产品和运营你说了算,说了就翻译(在合理的线上流程内)。方法一、首先照例,贴出两份文件。根据介绍(文档都是英文的),搭建需要的环境:Pootle:http://docs.translatehouse.or...serge:https://serge.io/一个很好的实现思路图(当然是盗图)2.在项目中使用统一的引用方式,如:
{{$t('Turnover-Total')}}3.将“脚本”添加到项目package.json:{"i18n":"node--experimental-modules--loader./build/custom-loader.mjsbuild/build-i18n.js"},4.build-i18n.js简单版(生成翻译文件)importi18nfrom'../src/assets/i18n/index-build.jsimportfsfrom'fs'console.log('Startfiltertranslation')for(letlocaleini18n){letdata=i18n[locale]//deleteredundantkeyfor(letkeyindata){if(data[key]!==''){console.info(`Deletetranslated:${key}`)删除数据[key]}}//输出翻译文件fs.writeFile(\`./src/assets/i18n/untranslate/${locale}.txt\`,JSON.stringify(data,Object.keys(data).sort(),2)+'\n',err=>{err&&console.error(err)})}console.log('filteringcompleted')多文件版本(在对应文件目录下生成翻译文件,解压publicfiles)//翻译文件路径constjsPath=['./webapp/pages/**/*/i18n/index.js']//writepublicindex.jsjsPath.forEach(p=>{glob.sync(p).forEach(p=>{fs.writeFile(p,`${data}`,err=>{err&&console.error(err)})})})//获取所有目录paths.forEach(p=>{glob.sync(p).forEach(file=>{letwritepath=file.replace(/[^<>/\\\|:""\*\?]+\.\w+$/,'')if(directory.indexOf(writepath)===-1){directory.push(writepath)}})})//写入翻译文件functiononParse(writepath){for(letlocaleini18n){glob.sync(`${writepath}i18n/${locale}.json`).forEach(file=>{++allFilefs.readFile(file,{encoding:'utf8'},(err,data)=>{if(err){console.error(err)return}data=JSON.parse(data)for(letkeyincurrentKeys){if(!(keyindata)){locale==="en_US"||"zh_CN"?data[key]=key:data[key]=''}}//删除多余的keyfor(letkeyindata){if(!(keyincurrentKeys)){删除数据[key]}}//输出翻译文件fs.writeFileSync(`${writepath}i18n/${locale}.json`,JSON.stringify(data,Object.keys(data).sort(),2)+'\n',err=>{err&&console.error(err)})})})}}//计算所有键和它们的数量functioncountCommonKeys(){jsonPath.forEach(p=>{glob.sync(p).forEach(file=>{++jsonNumberfs.readFile(file,{encoding:'utf8'},(err,data)=>{if(err){console.error(err)返回}data=JSON.parse(data)for(letkeyindata){if(!(keyincountKeys)){countKeys[key]=0//console.log(key)}else{//console.log(`---${key}---`)countKeys[key]++}}if(--jsonNumber===0){//console.log(countKeys)//getCommonKey()}})})})}//提取通用翻译文件functiongetCommonKey(){for(letlocaleini18n){letcommon={}[`./webapp/pages/**/*/i18n/${locale}.json`].forEach(p=>{glob.sync(p).forEach(file=>{fs.readFile(file,{encoding:'utf8'},(err,data)=>{data=JSON.parse(data)for(letkeyindata){if(countKeys[key]>3){common[key]=data[key]deletedata[key]}}})fs.writeFile(file,JSON.stringify(data,Object.keys(data).sort(),2)+'\n',{encoding:'utf8'},err=>{err&&console.error(err)})})fs.writeFile(`./webapp/assets/i18n/${locale}.json`,JSON.stringify(common,Object.keys(common).sort(),2)+'\n',{编码:'utf8'},err=>{err&&console.error(err)})})}}5.如何给服务器添加定时任务(执行间隔取决于服务器的性能)?分配帐户(谁拥有谁)并让他们随心所欲地翻译(当然,在开发过程中)。选择对应的语言,找到主键(可以使用中文或者英文作为主键,但是建议使用中文作为键,因为翻译和习惯的问题,减少重复带来的问题)