You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用i18next处理大量翻译文件并自动生成唯一key注入代码

i18next 自动生成唯一翻译key落地方案

核心逻辑是把「手动写key、手动维护翻译文件」的步骤放到编译/开发阶段自动完成,代码里只需要写原始文案即可,和react-intl的开发体验一致,针对1000+条文案的项目能减少90%以上的重复工作量。

方案一:Babel插件编译期注入(生产级项目首选,零侵入)

通过Babel在代码编译阶段扫描所有文案位置,自动生成唯一key、替换成i18next的t调用、同步写入多语言文件,全程不需要手动干预。

  • 基础依赖用babel-plugin-i18next-extract,不要用默认的key生成规则,自定义「文件相对路径+行号+原文短hash」的规则,保证key唯一、可溯源,不会因为文案微调丢失历史翻译关联。
  • 配置示例:
// babel.config.js
const crypto = require('crypto')
module.exports = {
  plugins: [
    [
      "i18next-extract",
      {
        keyAsDefaultValue: true, // 翻译缺失时直接展示原文,不会出现空白占位
        keyGenerator: (filePath, line, column, originalText) => {
          const shortPath = filePath.replace(process.cwd(), '').replace(/\//g, '.').replace(/^\./, '')
          const textHash = crypto.createHash('md5').update(originalText).digest('hex').slice(0, 6)
          return `${shortPath}:${line}:${textHash}`
        },
        outputPath: "src/locales/{{locale}}.json", // 提取到的新key自动写入对应语言包
        locales: ["zh-CN", "en-US", "ja-JP"], // 配置项目需要的语言列表
        discardOldKeys: true // 构建时自动清除代码里已经不存在的冗余key,避免翻译文件膨胀
      }
    ]
  ]
}
  • 开发时直接写原生文案即可,不需要手动写t函数和key:
// 开发者编写的代码
<div>提交订单</div>
<button>确认支付</button>

// 编译后自动转换的代码
<div>{t('src.pages.order.index:24:a1b2c3', '提交订单')}</div>
<button>{t('src.pages.order.index:25:d4e5f6', '确认支付')}</button>

*如果项目用TypeScript,搭配i18next-parser生成key的类型声明,编译时就能校验key是否存在,避免线上出问题。如果用react-i18next的Trans组件写嵌套JSX文案(比如带链接、加粗标签的文本),插件也能自动识别提取,不需要手动拆分文案。

方案二:轻量封装方案(适合不想改构建配置的中小项目)

自己封装一层翻译函数,在开发环境自动扫描调用位置生成key、写入翻译映射文件,生产环境直接读取预生成的key映射,改造成本极低。

  • 封装示例:
// src/utils/i18n.js
import i18n from 'i18next'
const crypto = require('crypto')
const fs = require('fs')
const path = require('path')
const keyMapPath = path.resolve(__dirname, '../locales/keyMap.json')
const keyMap = require(keyMapPath)

const generateKey = (filePath, line, text) => {
  const shortPath = filePath.replace(process.cwd(), '').replace(/\//g, '.').replace(/^\./, '')
  const textHash = crypto.createHash('md5').update(text).digest('hex').slice(0, 6)
  return `${shortPath}:${line}:${textHash}`
}

export const $t = (text, options = {}) => {
  if (process.env.NODE_ENV === 'development') {
    // 从调用栈取当前调用的文件和行号
    const callStack = new Error().stack.split('\n')[2]
    const matchRes = callStack.match(/\((.+):(\d+):\d+\)$/) || callStack.match(/at (.+):(\d+):\d+$/)
    if (matchRes) {
      const [, filePath, line] = matchRes
      const key = generateKey(filePath, line, text)
      if (!keyMap[key]) {
        keyMap[key] = { 'zh-CN': text }
        fs.writeFileSync(keyMapPath, JSON.stringify(keyMap, null, 2))
      }
      return i18n.t(key, { defaultValue: text, ...options })
    }
  }
  // 生产环境直接读取预先生成好的key映射
  const existKey = Object.keys(keyMap).find(k => keyMap[k]['zh-CN'] === text)
  return i18n.t(existKey || text, { defaultValue: text, ...options })
}
  • 使用时直接调用$t('提交订单')即可,不需要手动维护key。

关键避坑点

  • 不要直接用原文作为key:一旦文案修改一个字,所有语言的翻译关联会直接断开,带位置+短hash的key就算文案调整,只会生成新key,旧翻译可以批量迁移
  • 不要用自增数字作为key:多人协作时极易出现key冲突,合并代码时冲突率极高
  • 每次构建加key扫描逻辑:自动清理代码中已经不再引用的旧key,避免翻译文件堆到几千条无效内容

内容的提问来源于stack exchange,提问作者w x

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 04:27:21