翻译迁移google sheets方案

1. 介绍

之前使用的石墨旧方案为:将翻译内容放在另一个仓库项目中,独立部署,造成了很多不必要的麻烦和bug。结合fox项目中使用过的google sheets方案,决定将其迁移至google sheets并使用googleapis在构建时拉取翻译文本。

2. 流程

  1. 首先将之前在石墨文档的翻译导出excel文件,再导入到google sheets中。

  2. 要在项目中获取翻译文本,我们选择node.js在项目构建前通过googleapis拉取翻译文本。官方教程

    1. 从官方教程里按教程下载凭证文件

    2. 项目中安装googleapis依赖

    3. 复制案例并执行确保没问题

    4. 修改listMajors的代码,其中分为3步:

    5. 使用spreadsheetId连接指定表格spreadsheets.get()

    6. 获取表格中不同分页的内容(通过get方法的range属性中设置title实现),并将其转化为根据不同语言区分的对象数组,对象存储了翻译对应的名值对

    7. 转化对象为json格式并导出json文件,在文件尾部加上crypto库生成的hash值,将全部文件路径整合在langMap.json文件

  3. 修改项目vue-i18n设置,通过import导入langMap,通过import()异步引入翻译包

  4. 在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,
      )
    })
  })
}

4.参考

vue-i18n懒加载

node.js获取hash值

import()语法

官方api文档

官方快速教程