关于 i18n
面向开发者的国际化工作流技能,规范语言配置、翻译键、校验流程及用户可见文本的处理。
主要功能
- 01先读取语言与模块配置
- 02按模块组织翻译键
- 03为所有支持语言添加键
- 04重新生成类型并校验翻译
- 05检测硬编码界面文本
适用场景
- 01为功能添加翻译文本
- 02新增语言模块
- 03提交前检查本地化改动
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ iofficeai/ aionui --skill i18n安装后在 Claude Code 中输入/i18n确认已加载。
详细介绍
i18n 技能
国际化的标准与工作流。所有用户可见的文本都必须使用 i18n。
开始时声明:“我正在使用 i18n 技能,以确保正确的国际化。”
重要:先读取配置
在进行任何 i18n 工作之前,务必先读取 src/common/config/i18n-config.json,以获取当前支持的语言和模块列表。切勿假定数量是固定的——自本技能编写以来,语言和模块可能已被添加或移除。
cat src/common/config/i18n-config.json
此文件是唯一事实来源。所有脚本、运行时代码以及本工作流都依赖它。
文件结构
src/common/config/i18n-config.json # Single source of truth: languages, modules
src/renderer/i18n/
├── index.ts # i18next configuration
├── i18n-keys.d.ts # AUTO-GENERATED — do not edit manually
└── locales/
├── <lang>/ # One directory per language in i18n-config.json
│ ├── index.ts # Barrel import for all modules
│ ├── common.json # One JSON per module in i18n-config.json
│ ├── conversation.json
│ └── ...
└── ...
关键事实
- 参考语言:由
i18n-config.json中的referenceLanguage定义(当前为en-US) - 支持的语言:由
supportedLanguages数组定义——读取该文件以获取当前列表 - 模块:由
modules数组定义——读取该文件以获取当前列表
键结构
代码中的键使用带命名空间的点号表示法:t('module.key') 或 t('module.nested.key')。
在每个模块的 JSON 文件中,键可以是扁平或嵌套的:
// common.json — flat keys
{
"send": "Send",
"cancel": "Cancel",
"copySuccess": "Copied"
}
// cron.json — nested keys
{
"scheduledTasks": "Scheduled Tasks",
"status": {
"active": "Active",
"paused": "Paused"
}
}
在代码中:
t('common.send'); // flat key in common.json
t('cron.status.active'); // nested key in cron.json
键命名规则
- 键名使用 camelCase:
copySuccess、scheduledTasks - 通过嵌套对相关键进行分组:
status.active、actions.pause - 可复用的文本放在
common.json中:save、cancel、delete、confirm 等 - 特定功能的文本放在对应的模块中
常用后缀
| 后缀 | 用途 |
|---|---|
title | 区块/页面标题 |
placeholder | 输入框占位符 |
label | 表单标签 |
success / error | 状态消息 |
confirm | 确认对话框 |
empty | 空状态消息 |
tooltip | 工具提示文本 |
添加新文本——工作流
步骤 1:读取 src/common/config/i18n-config.json
获取当前的语言列表和模块列表。不要跳过此步骤。
步骤 2:检查现有键
在添加新键之前,搜索是否已有类似的键:
grep -r "keyword" src/renderer/i18n/locales/en-US/
尽可能复用 common.* 键。
步骤 3:选择正确的模块
将模块与功能区域相匹配。如果没有合适的模块,考虑是否需要新建一个模块(参见下文“添加新模块”)。
步骤 4:添加到所有语言目录
至关重要:每个新键都必须添加到 supportedLanguages 中的每一种语言。对每个键使用以下检查清单:
-
en-US/<module>.json— 参考语言(在步骤 3 中添加) -
zh-CN/<module>.json— 已添加 -
zh-TW/<module>.json— 已添加 -
src/common/config/i18n-config.json→supportedLanguages中列出的任何其他语言 — 已添加
只要有一种语言缺少某个键,node scripts/check-i18n.js 就会在 CI 中失败。
步骤 5:在组件中使用
import { useTranslation } from 'react-i18next';
function MyComponent() {
const { t } = useTranslation();
return <button>{t('common.save')}</button>;
}
步骤 6:重新生成类型并验证
按顺序运行以下两条命令——两者都必须通过才能提交:
bun run i18n:types # Step A: regenerate i18n-keys.d.ts from reference locale
node scripts/check-i18n.js # Step B: validate structure, keys, and type sync
i18n:types必须在check-i18n.js之前运行——该检查会验证生成的文件- 如果
check-i18n.js以错误(❌)退出,请在继续之前修复它们 - 如果
check-i18n.js仅以警告(⚠️)退出,请检查后但仍可继续 - 切勿使用过期的
i18n-keys.d.ts提交
添加新模块
- 将模块名添加到
src/common/config/i18n-config.json→modules数组 - 在每一种语言目录中创建
<module>.json(读取supportedLanguages以了解具体有哪些) - 在每个语言的
index.ts中添加 import + export - 运行
bun run i18n:types以重新生成类型定义 - 运行
node scripts/check-i18n.js进行验证
硬编码字符串检测
禁止的模式
切勿在 JSX 中使用硬编码的中文/英文文本:
// Bad
<span>重命名</span>
<span>Delete</span>
{name || '新对话'}
// Good
<span>{t('common.rename')}</span>
<span>{t('common.delete')}</span>
{name || t('conversation.newConversation')}
例外情况
- 代码注释(任何语言均可)
console.log()/ 调试输出- 不向用户展示的内部字符串常量
插值
变量
{
"taskCount": "{{count}} task(s)",
"greeting": "Hello, {{name}}!"
}
t('cron.taskCount', { count: 5 });
翻译中的 HTML
对于复杂标记,请使用 Trans 组件:
import { Trans } from 'react-i18next';
<Trans i18nKey='cron.countdown'>
Task <strong>{{ taskName }}</strong> in <span>{{ countdown }}</span>
</Trans>;
zh-TW 维护
大多数术语可以从 zh-CN 自动转换,但有些需要人工审核:
| zh-CN | zh-TW | 说明 |
|---|---|---|
| 视频 | 影片 | 术语不同 |
| 软件 | 軟體 | 术语不同 |
| 信息 | 訊息 | 术语不同 |
| 默认 | 預設 | 术语不同 |
快速检查
在提交包含新文本的代码之前:
- 阅读
src/common/config/i18n-config.json以获取当前语言和模块 - 所有用户可见文本都使用
t()函数 - 新键已添加到
supportedLanguages中的每个语言目录 - JSX 中没有硬编码的中文/英文
- 已审核 zh-TW 的术语差异
- 已先运行
bun run i18n:types(重新生成i18n-keys.d.ts) - 在重新生成类型后,
node scripts/check-i18n.js已通过(无错误)
常见错误
| 错误 | 正确 |
|---|---|
| 假设语言数量固定 | 始终阅读 i18n-config.json |
| 仅向部分语言环境添加键 | 添加到 supportedLanguages 中的每个语言环境 |
手动编辑 i18n-keys.d.ts | 运行 bun run i18n:types 来生成 |
使用 t("New Chat") | 定义键:t("conversation.newChat") |
新模块未更新 i18n-config.json | 先更新配置,再创建文件 |
添加了模块 JSON 但未更新 index.ts | 必须在每个语言环境的 index.ts 中添加 import + export |
评论
支持 Markdown