1. 介绍
之前使用的石墨旧方案为:将翻译内容放在另一个仓库项目中,独立部署,造成了很多不必要的麻烦和bug。结合fox项目中使用过的google sheets方案,决定将其迁移至google sheets并使用googleapis在构建时拉取翻译文本。
2. 流程
首先将之前在石墨文档的翻译导出excel文件,再导入到google sheets中。
-
要在项目中获取翻译文本,我们选择node.js在项目构建前通过googleapis拉取翻译文本。官方教程
从官方教程里按教程下载凭证文件
项目中安装googleapis依赖
复制案例并执行确保没问题
修改listMajors的代码,其中分为3步:
使用spreadsheetId连接指定表格
spreadsheets.get()
获取表格中不同分页的内容(通过get方法的range属性中设置title实现),并将其转化为根据不同语言区分的对象数组,对象存储了翻译对应的名值对
转化对象为json格式并导出json文件,在文件尾部加上crypto库生成的hash值,将全部文件路径整合在langMap.json文件
修改项目vue-i18n设置,通过import导入langMap,通过import()异步引入翻译包
在package.json与ci文件中增加执行拉取翻译的命令
3. 代码
// 上面省略凭证相关代码
const SheetHashMap = {}
let Sheetslength = 0
function exportSheetData(sheetData, title, Locale) {
Locale.forEach((lang, index) => {
// fs.ensureDirSync(`${OUTPUT_DIR}/${title}`)
fs.mkdirSync(`${OUTPUT_DIR}/${title}`, { recursive: true })
const sheetStringData = JSON.stringify(sheetData[index])
const hash = crypto
.createHash('md5')
.update(sheetStringData)
.digest('hex')
Object.assign(SheetHashMap, { [`${title}-${lang}`]: `${title}-${lang}-${hash}.json` })
fs.writeFileSync(
`${OUTPUT_DIR}/${title}/${title}-${lang}-${hash}.json`,
sheetStringData,
'utf-8',
)
console.log(`build /${title}/${title}-${lang}-${hash}.json`)
})
if (0 === (Sheetslength -= 1)) {
fs.writeFileSync(`${OUTPUT_DIR}/langMap.json`, JSON.stringify(SheetHashMap), 'utf-8')
console.log('🎉 SUCCESS: check on /src/locales/')
}
}
function handleGetSheetData(err, sheetRes) {
if (err) return console.log('The API returned an error: ' + err)
const rows = sheetRes.data.values
const sheetTitle = sheetRes.data.range.split('!')[0]
const Locale = rows[0].splice(1)
const sheetData = Array.from({ length: Locale.length }, () => new Object())
rows.splice(1).forEach(rowData => {
const rowKey = `${sheetTitle}_${rowData[0]}`
rowData.splice(1).forEach((value, index) => {
sheetData[index][rowKey] = value
})
})
exportSheetData(sheetData, sheetTitle, Locale)
}
function connectSheets(auth) {
const doc = google.sheets({ version: 'v4', auth })
doc.spreadsheets.get({ spreadsheetId: SHEETS_ID }, (err, res) => {
if (err) return console.log('The API returned an error: ' + err)
// clear dir
rimraf(OUTPUT_DIR)
const sheets = res.data.sheets
Sheetslength = sheets.length
sheets.forEach(sheet => {
const title = sheet.properties.title
doc.spreadsheets.values.get(
{ spreadsheetId: SHEETS_ID, range: `${title}!A:C` },
handleGetSheetData,
)
})
})
}