🌍 专为 React Native/React/TypeScript 项目设计的国际化工具
- 🔍 自动扫描: 智能识别代码中的中文文本
- 🚫 智能忽略: 自动忽略 testID、注释等无需翻译的内容
- 🔄 一键替换: 自动将中文替换为
t()函数调用 - 📊 Excel管理: 使用 Excel 管理翻译,方便团队协作
- 🔗 GitLab集成: 自动生成源码链接,快速定位
- 📈 增量更新: 支持版本迭代的增量翻译管理
- 🏷️ 按钮 label 分类: 自动识别 JSX 属性、Alert 按钮、按钮包 Text 等场景,按
category标记,AI 翻译时按极简规则生成 1~3 词译文
npm install hecom-i18n-tools -D# 直接使用 npx 运行,无需全局安装
npx hecom-i18n-tools scan -s 'src' -o 'i18n-result.xlsx'
npx hecom-i18n-tools replace --excel=i18n-result.xlsx --importPath='@/utils/i18n'
npx hecom-i18n-tools gen# 1. 扫描中文文本并生成 Excel
hecom-i18n-tools scan -s 'src' -o 'i18n-result.xlsx'
# 2. 替换代码中的中文为 t() 调用
hecom-i18n-tools replace --excel=i18n-result.xlsx --importPath='@/utils/i18n'
# 3. 生成语言包文件
hecom-i18n-tools genfunction App() {
return (
<View>
<Text>欢迎使用我们的应用</Text>
<Button title="确认提交" onPress={handleSubmit} />
<Text testID="测试标识">用户名</Text> // testID 自动忽略
</View>
);
}import { t } from '@/utils/i18n';
function App() {
return (
<View>
<Text>{t("i18n_abc123def")}</Text>
<Button title={t("i18n_def456ghi")} onPress={handleSubmit} />
<Text testID="测试标识">{t("i18n_ghi789jkl")}</Text>
</View>
);
}| key | zh | en | file | line |
|---|---|---|---|---|
| i18n_abc123def | 欢迎使用我们的应用 | Welcome to our app | src/App.tsx | 4 |
| i18n_def456ghi | 确认提交 | Confirm | src/App.tsx | 5 |
| i18n_ghi789jkl | 用户名 | Username | src/App.tsx | 6 |
hecom-i18n-tools scan [options]
选项:
-s, --src <paths> 源码目录,支持多个路径
-o, --out <file> 输出 Excel 文件路径
--gitlab <url> GitLab 项目地址
--config <file> 配置文件路径hecom-i18n-tools replace [options]
选项:
--excel <file> Excel 翻译文件路径
--file <file> 只处理指定文件
--importPath <path> i18n 导入路径
--fixLint 自动修复 ESLinthecom-i18n-tools gen [options]
选项:
--excel <file> Excel 文件路径
--output <dir> 语言包输出目录hecom-i18n-tools translate [options]
选项:
-e, --excel <file> 输入 Excel 文件路径
-o, --out <file> 输出 Excel 文件路径(可与输入相同,原地覆盖)
-k, --api-key <key> DashScope API Key
--keys <keys> 仅翻译指定 key(逗号分隔)
--langs <langs> 仅翻译指定语言列(逗号分隔,如 en,th)
--python <path> Python 可执行路径(默认: python3)
--prompt <template> 自定义 Prompt 模板(需含 {text} 和 {target_lang})
--prompt-file <file> Prompt 模板文件路径
--category-column <name> 承载 category 元数据的列名(默认: category;传空字符串禁用)hecom-i18n-tools flow [options]
选项:
-s, --src <paths> 源代码目录(逗号分隔)
-e, --excel <file> 中间 Excel 文件路径
-o, --out <dir> 语言包输出目录
-i, --importPath <path> i18n 工具模块的 importPath,如 core/util/i18n
-g, --gitlab <url> GitLab 仓库 URL 前缀
-c, --config <file> 配置文件路径(含 email 等配置)
-m, --master <file> 主 Excel 文件路径(可选)
-k, --api-key <key> DashScope API Key(不填则跳过翻译步骤)
--langs <langs> 翻译时仅处理指定语言列
--python <path> Python 可执行路径(默认: python3)
--prompt-file <file> Prompt 模板文件路径
-r, --conflict-report <f> 冲突报告输出路径
-l, --fixLint <bool> 替换后是否运行 Prettier 格式化(默认: true)
-p, --prettier-config <f> Prettier 配置文件路径工具在扫描时会按 AST 上下文给每条中文字符串打 category 标记:
button-label:按钮 / Tab / 菜单项 / 字段名等极短文案normal:其他 UI 文案
命中规则(按优先级):
- 父链是
JSXAttribute且属性名命中jsxAttributes白名单(如<Button title="确认">) - 父链是
alertCallees调用的数组参数,且是该参数ObjectExpression的text字段(如Alert.alert(...)的按钮文字) - JSXText 祖先链上存在
buttonComponents白名单标签(如<Button><Text>登录</Text></Button>) - 上一行注释包含
inlineComment标记(手动兜底)
buttonLabelRules 通过配置文件注入:
// i18nScannerOptions.js
module.exports = {
buttonLabelRules: {
jsxAttributes: ['title', 'okText', 'cancelText', 'backTitle', 'tabLabel', 'label'],
alertCallees: ['Alert', 'alert'],
buttonComponents: ['Button', 'TouchableOpacity', 'Pressable', 'BottomBtn'],
inlineComment: '// @i18n:button-label',
ancestorDepth: 4,
},
};Prompt 模板支持 {category} 占位符,AI 会按类别切换翻译风格:
category == "button-label"→ 英文 1~3 个 Title Case 单词(Cancel / Confirm / Save / Upload / Retry / Set as Latest / Open with…)- 其他 → 完整自然的 UI 文案
Prompt 模板样例见 examples/ 目录。
- 🐛 问题反馈: GitHub Issues
- 📖 详细文档: 查看项目内的 Markdown 文档
- 💬 技术讨论: 联系项目维护团队
MIT © HECOM
让国际化变得简单高效! 🌍
- key: 唯一key
- zh: 中文
- file: 文件路径
- line: 行号
- gitlab: 跳转链接
- en/ja...: 各语言
| 参数 | 必需 | 描述 |
|---|---|---|
| -s, --dist | 是 | 源代码目录(支持多个,用逗号分隔) |
| -o, --out | 是 | 输出Excel路径 |
| -g, --gitlab | 否 | GitLab仓库URL前缀 |
| -c, --config | 否 | 配置文件路径 |
| 参数 | 必需 | 描述 |
|---|---|---|
| -e, --excel | 是 | Excel文件路径 |
| -i, --importPath | 是 | import路径 |
| -f, --file | 否 | 仅处理指定文件 |
| -l, --fixLint | 否 | 是否修复lint |
| 参数 | 必需 | 描述 |
|---|---|---|
| -e, --excel | 是 | Excel文件路径 |
| -o, --out | 是 | 输出目录 |
| 参数 | 必需 | 描述 |
|---|---|---|
| -e, --excel | 是 | 输入 Excel 文件路径 |
| -o, --out | 是 | 输出 Excel 文件路径(可与输入相同,原地覆盖) |
| -k, --api-key | 是 | DashScope API Key |
| --keys | 否 | 仅翻译指定 key(逗号分隔) |
| --langs | 否 | 仅翻译指定语言列(逗号分隔,如 en,th) |
| --python | 否 | Python 可执行路径(默认: python3) |
| --prompt | 否 | 自定义 Prompt 模板字符串(需含 {text} 和 {target_lang}) |
| --prompt-file | 否 | Prompt 模板文件路径 |
| --category-column | 否 | category 元数据列名(默认: category;传空字符串禁用) |
| 参数 | 必需 | 描述 |
|---|---|---|
| -s, --src | 是 | 源代码目录(支持逗号分隔) |
| -e, --excel | 是 | 中间 Excel 文件路径 |
| -o, --out | 是 | 语言包输出目录 |
| -i, --importPath | 是 | i18n 工具模块的 importPath |
| -g, --gitlab | 否 | GitLab 仓库 URL 前缀 |
| -c, --config | 否 | 配置文件路径 |
| -m, --master | 否 | 主 Excel 文件路径(合并后删除当前 Excel) |
| -k, --api-key | 否 | DashScope API Key(不填则跳过翻译步骤) |
| --langs | 否 | 翻译时仅处理指定语言列 |
| --python | 否 | Python 可执行路径(默认: python3) |
| --prompt-file | 否 | Prompt 模板文件路径 |
| -r, --conflict-report | 否 | 冲突报告输出路径(默认: /conflicts.json) |
| -l, --fixLint | 否 | 替换后是否运行 Prettier 格式化(默认: true) |
| -p, --prettier-config | 否 | Prettier 配置文件路径 |
项目内置最小测试脚本验证以下行为:
- 无冲突:正常生成多语言 json。
- 冲突(已有 json 中同 key 不同翻译):应阻止生成,不覆盖旧文件,并生成
conflicts-*.json报告,Excel 原文件不删除。
运行测试:
yarn test测试脚本位置:test/run-tests.js (使用 Node 原生 assert,无需额外依赖)。
扫描时默认会忽略以下日志对象/方法中的中文:
- 对象:
console,UnionLog - 方法:
log,warn,error,info,debug,trace,verbose,fatal
现在可通过配置文件追加自定义日志(例如忽略 Sentry.captureMessage 中的中文):
提示:配置项是“追加”而不是“覆盖”,仍会保留默认忽略的 console/UnionLog 及其方法。