国际化 i18n 项目中怎么实现自动化生成 json 数据,而不是通过手动添加翻译字段呢?
通常支持 i18n 的项目,都需要提供一个对应的国际化 json 数据,但是手动维护 json 数据比较麻烦,怎么才能实现自动或者一键生成 json 数据呢?
本文参与了SegmentFault 思否面试闯关挑战赛,欢迎正在阅读的你也加入。
回答:
其实有很多的项目在实现这个功能,比如说之前SF社区就有人自推过自己实现的一个 i18n
管理项目 ? vue-i18n-generator - 一款方便编辑语言包代码的工具。
最近也有人分享过文章 对国际化 i18n 项目的一点思考,里面有提到过几种维护的方式,都可以借鉴一下。
其实使用 i18n-ally 开发起来就已经很方便了。
我自己呢就是偷懒,其实是因为配置 i18n Ally
的时候总是失败,所以就自己写了一个构建脚本,维护的时候是去维护一个数组:
// /locale/modules/common/button.jsimport { transferLangConfig } from '@/i18n/config'
const config = {
// 通用部分
"search": ['搜索', '檢索', 'Search'],
"reset": ['重置', '重置', 'Reset'],
"clear": ['清空', '清空', 'Clear'],
"add": ['新增', '新增', 'Add'],
"confirm": ['确认', '確認', 'Confirm'],
"select": ['选择', '選擇', 'Select'],
"delete": ['删除', '刪除', 'Delete'],
"cancel": ['取消', '取消', 'Cancel'],
"remove": ['移除', '移除', 'Remove'],
"yes": ['是', '是', 'Yes'],
"no": ['否', '否', 'No'],
// ...
}
export default transferLangConfig(config)
最后通过 "i18n-gen": "node -r esm ./locale/i18nGen.js"
这个脚本执行生成对应语言的 json
文件,大概思路如下:
// /locale/i18nGen.jsimport { writeFile } from 'fs'
import { languageList } from './config.js'
import localeData from './modules/index.js'
// uni-app 不支持多层JSON数据需要转换成单层 => "common.button.submit":"提交" 这样的形式
function transfSingleLayerJSON(data, fatherKey=''){
let tempObj = {}
for(let key in data){
let prefix = `${fatherKey?fatherKey+'.':''}${key}`
if(typeof data[key] === 'object') {
Object.assign(tempObj, transfSingleLayerJSON(data[key], prefix))
} else {
tempObj[prefix] = data[key]
}
}
return tempObj
}
languageList.forEach(lang => {
const tempLocale = transfSingleLayerJSON(localeData[lang])
writeFile(`./locale/${lang}.json`, JSON.stringify(tempLocale),()=>{});
})
一些其他的相关JS示例
// /locale/config.jsexport const languageList = ['zh-Hans','zh-Hant', 'en']
// 创建一个空i18n对象
const createEmptyLangConfig = () => Object.fromEntries(new Map(languageList.map(key => [key, {}])))
// 配置文件转i18n对象
export const transferLangConfig = (data) => {
const langConfig = createEmptyLangConfig()
for (const key in data) {
languageList.forEach((lang, index) => {
langConfig[lang][key] = data[key][index]
})
}
return langConfig
}
// /locale/modules/index.jsimport system from './system/index.js'
import common from './common/index.js'
export default {
en:{
...components['en'],
system:system['en'],
common:common['en'],
...
},
'zh-Hans': {
...components['zh-Hans'],
system:system['zh-Hans'],
common:common['zh-Hans'],
...
},
'zh-Hant': {
...components['zh-Hant'],
system:system['zh-Hant'],
common:common['zh-Hant'],
...
}
}
// /locale/modules/common/index.jsimport { transferLangConfig } from '../../config.js'
import button from './button.js'
...
// 公共部分
const common = transferLangConfig({
"no-data": ['没有数据', '沒有數據', 'No Data'],
})
export default {
'zh-Hans': {
...common['zh-Hans'],
button: button['zh-Hans'],
...
},
'zh-Hant': {
...common['zh-Hant'],
button: button['zh-Hant'],
...
},
'en': {
...common['en'],
button: button['en'],
...
}
}
至于为什么引入的时候每一次都手动去 xxx['en']
主要是因为想比较随意的命名。有些时候并不像层级那么深。想要可以很快的使用,又想可以聚合在一起维护。
本文参与了SegmentFault 思否面试闯关挑战赛,欢迎正在阅读的你也加入。
以上是 国际化 i18n 项目中怎么实现自动化生成 json 数据,而不是通过手动添加翻译字段呢? 的全部内容, 来源链接: utcz.com/p/933805.html