Happy 应用 i18n 翻译实践指南:基于 i18n-translator 子代理的多语言翻译工作流
发布时间:2026/9/20 22:36:30来源:尧图网络
Happy 应用 i18n 翻译实践指南基于 i18n-translator 子代理的多语言翻译工作流【免费下载链接】happyMobile and Web client for Codex and Claude Code, with realtime voice, encryption and fully featured项目地址: https://gitcode.com/gh_mirrors/happy20/happy本篇技术指南围绕 Happy 项目Codex 与 Claude Code 的移动端/Web 客户端中的国际化i18n翻译工作展开核心对象是 i18n-translator 子代理定义 与其背后的对象化、类型安全的翻译体系。读者将掌握Happy 应用的翻译文件结构与 key 命名规范、从「新增界面文案」到「全语言文件落地」的完整翻译流程、静态字符串与动态函数化翻译的处理方式以及如何借助类型系统与一致性校验脚本保证多语言翻译的质量。一、背景Happy 应用的对象化 i18n 体系在深入子代理职责之前先理解它服务的翻译基础设施。Happy 应用的国际化实现位于 packages/happy-app/sources/text/其核心特点如下零外部依赖不引入 i18n 库采用纯 TypeScript 对象 函数的方案完整类型安全翻译 key 与参数形状在编译期校验支持 IntelliSense混合值类型同一对象内既允许字符串常量静态文本也允许带类型参数的函数动态文本熟悉的 API对外暴露标准t(key, params)调用格式。当前仓库实际支持的语言为10 种见 sources/text/_all.ts 中SupportedLanguage联合类型语言代码语言语言代码语言enEnglish默认语言ptPortuguêsruРусскийcaCatalàplPolskizh-Hans中文(简体)esEspañolzh-Hant中文(繁體)itItalianoja日本語i18n-translator 子代理文档以 en、ru、pl、es 四种语言为例展开翻译准则这与仓库的初始支持范围一致后续扩展的 it、pt、ca、zh-Hans、zh-Hant、ja 均遵循同一套结构约束。语言对象的权威结构由英文文件 sources/text/_default.ts 定义export const en与导出类型Translations/TranslationStructure其余语言文件如 translations/ru.ts、translations/pl.ts以: TranslationStructure标注类型由 TypeScript 强制其结构与英文完全一致——任何缺 key、多 key 或参数类型不符都会在编译期报错。这正是子代理「必须更新所有语言文件」约束的底层保障。二、i18n-translator 子代理的定位与触发场景i18n-translator.md 是 Happy 仓库中为 Claude Code及兼容 Agent定义的专用子代理用于在代码库引入任何新的用户可见文本时介入。其description字段明确了适用范围当需要向应用添加新的可翻译字符串或验证既有翻译时使用该代理。包括添加需要翻译的新 UI 文本、确保各语言文件翻译一致、验证翻译是否符合 UI 上下文标题、按钮、多行文本以及检查所有必需语言是否都包含新字符串。典型触发场景文档中的示例新增功能文案用户添加「网络同步失败」这类新错误提示时代理负责为所有语言补齐翻译新界面落地创建含标题、描述、保存按钮的新设置页后代理接手所有 UI 文本的翻译翻译缺失修复设置页的「Cancel」按钮在非英语语言中缺失时代理核查并补齐全部语言文件。子代理的配置属性frontmatter还声明了可用工具Glob、Grep、LS、Read、Edit、MultiEdit、Write 等、推荐模型opus与标识色green使其在 Agent 工作流中可被按需调用。三、核心职责一翻译上下文分析翻译不是逐词替换子代理要求在任何翻译动笔之前先做上下文分析这也是其Analyze Translation Context职责的核心识别使用位置该字符串出现在哪个界面/组件例如设置页、会话列表、错误弹窗判断 UI 元素类型按钮、标题、段落、错误信息等不同类型对措辞的要求截然不同评估空间约束单行按钮必须简短多行描述可以更完整——这直接决定译文长度确定语气正式formal、随意casual、技术technical、友好friendly需与产品基调一致检索既有翻译确认common公共分区中是否已有语义相同的翻译避免重复造词维持术语一致性。四、核心职责二各语言翻译准则子代理文档按语言给出了明确的翻译风格指引English (en)清晰、简洁、行动导向clear, concise, action-orientedRussian (ru)正式而友好注意名词/形容词的格变化case declensionsPolish (pl)保持尊重语气注意阴阳性gender forms与格Spanish (es)采用适合多地区的中性西班牙语neutral Spanish。此外有一条跨语言通用原则CLI、API、URL、JSON 等全球通用的技术术语保留原文不做本地化。这条原则在仓库的翻译一致性校验脚本 sources/scripts/compareTranslations.ts 中有直接体现——脚本内置了[GitHub, URL, API, CLI, OAuth, QR, JSON, HTTP, HTTPS, ID, PID]白名单当非英语翻译与英文原文相同时若命中技术术语则判定为「合理保留」而非「漏译」。复数规则的源码印证文档强调「为每种语言正确处理单复数形式」。Happy 仓库用两种复数辅助函数落实这一要求英文sources/text/_default.ts采用简单二元判断function plural({ count, singular, plural }: { count: number; singular: string; plural: string }): string { return count 1 ? singular : plural; }俄语sources/text/translations/ru.ts遵循斯拉夫语系三种复数形式one / few / many规则function plural({ count, one, few, many }: { count: number; one: string; few: string; many: string }): string { const n Math.abs(count); const n10 n % 10; const n100 n % 100; // Rule: ends in 1 but not 11 if (n10 1 n100 ! 11) return one; // Rule: ends in 2-4 but not 12-14 if (n10 2 n10 4 (n100 10 || n100 20)) return few; // Rule: everything else (0, 5-9, 11-19, etc.) return many; }波兰语sources/text/translations/pl.ts同样是三种形式但边界规则不同n 1用 one2–4 且非 12–14 用 few其余用 many。这说明复数规则必须按语言单独实现翻译者不能假定「复数 加 s」。五、核心职责三遵循项目结构与 key 命名规范子代理要求新增翻译时严格遵守 Happy 现有代码库的模式分区放置字符串应放入合适的分区common、settings、session、errors、modals、components等。从 sources/text/_default.ts 可以看到实际存在的顶层分区voiceStatusBar、tabs、inbox、common、profile、status、time、connect、settings、settingsAppearance等复用优先在common分区已有合适翻译时优先复用而不是新建例如common.cancel、common.save、common.ok描述性层级 key采用点分层级命名如newSession.machineOffline。仓库中大量实例可佐证例如settings.githubConnected、settings.machineStatus、status.lastSeen全语言同步新增 key 必须写入所有语言文件这与 sources/text/index.ts 中translations对象以RecordSupportedLanguage, TranslationStructure类型约束全部 10 种语言的结构完全对应。翻译值的两种形态文档将字符串分为两类仓库实现一一对应静态字符串String constants——不变文本key-value 直查common: { cancel: Cancel, authenticate: Authenticate, save: Save, // ... }动态字符串Functions with typed parameters——带类型化参数对象的函数运行时直接调用status: { lastSeen: ({ time }: { time: string }) last seen ${time}, }, settings: { machineStatus: ({ name, status }: { name: string; status: online | offline }) ${name} is ${status}, featureToggled: ({ feature, enabled }: { feature: string; enabled: boolean }) ${feature} ${enabled ? enabled : disabled}, }, time: { minutesAgo: ({ count }: { count: number }) ${count} minute${count ! 1 ? s : } ago, },值得注意machineStatus的status参数被约束为online | offline联合类型featureToggled的enabled为布尔值——这意味着翻译函数内的条件逻辑完全由类型系统兜底传错参数会在编译期直接报错。六、类型系统如何支撑翻译质量Happy 的 i18n 层把「翻译质量」的一部分前置到了编译期。sources/text/index.ts 中定义了一组关键类型NestedKeysTL19-L29递归提取嵌套翻译对象的所有点分 key例如common.cancel、settings.title、time.minutesAgoGetValueT, PathL34-L40按路径定位值类型GetParamsVL47-L52若值是函数则提取其首个参数类型若是字符串则返回void无需参数。由此得到TranslationKey与TranslationParams两个导出类型并在t()函数签名L167-L172中动态计算参数需求export function tK extends TranslationKey( key: K, ...args: GetParamsGetValueTranslations, K extends void ? [] : [GetParamsGetValueTranslations, K] ): string效果是以下错误写法全部在编译期被拦截t(common.cancel, { extra: param }) // Error: Expected 0 arguments t(common.welcome) // Error: Missing required parameter t(common.welcome, { wrongKey: x }) // Error: Object must have name property t(common.welcome, { name: 123 }) // Error: name must be string t(invalid.key) // Error: Key doesnt existt()运行时的行为也很清晰L173-L207按点分路径取值 → 函数则携带参数调用、字符串则直接返回 → 缺 key 或类型异常时打印console.warn/console.error并回退返回 key 本身保证 UI 永不因翻译问题崩溃。七、核心职责四与五质量验证与字符串类型处理质量验证清单子代理的Verify Translation Quality职责包含各语言语法正确性、是否符合 UI 尺寸约束、与既有翻译的一致性、右到左RTL语言适配的考虑如适用、动态翻译中参数用法的校验。五种字符串处理要点静态字符串简单 key-value直接放置即可动态字符串带类型参数函数参数命名要自解释复数化按语言规则选择 one/few/many见第四节源码日期/时间格式尊重各 locale 的文化习惯仓库中time.minutesAgo、time.hoursAgo、time.daysAgo即为可本地化的相对时间表达参数设计最佳实践来自 sources/text/README.md使用描述性参数名、恰当使用可选参数如date?: string、用联合类型做严格枚举约束如time: morning | afternoon | evening、把复杂条件逻辑放进翻译函数如files/online/syncing组合判断。一致性的自动化校验除了类型系统仓库还提供脚本 sources/scripts/compareTranslations.ts 用于人工校验翻译完整性。它以英文为基准递归提取各语言全部 key逐一报告缺失 keyMissing该语言缺少英文中存在的 key未翻译字符串Untranslated非英语语言中仍与英文原文相同且非技术术语白名单的字符串多余 keyExtra英文中不存在、疑似冗余或拼写错误的 key最终输出 Markdown 格式的翻译完整性报告与抽样验证如common.cancel、errors.networkError在各语言下的值。八、子代理的标准工作流与输出格式工作流五步文档规定子代理收到翻译请求后按序执行澄清上下文若信息不足先询问——该字符串用于哪个界面/组件什么类型的 UI 元素是否有尺寸约束传达什么动作或信息审查既有翻译维持术语一致性输出全语言翻译为所有必需语言提供译文若做了文化适配则附解释建议 key 名与分区位置符合camelCase描述性层级命名以代码块格式化输出展示各语言文件的改动片段。示例输出格式文档原文继承新增「同步时网络连接失败」错误提示的标准输出形态如下// sources/text/translations/en.ts export const en { // ... existing translations errors: { // ... existing errors networkSync: Network connection failed during sync, } } // sources/text/translations/ru.ts export const ru { // ... existing translations errors: { // ... existing errors networkSync: Сбой сетевого подключения во время синхронизации, } } // sources/text/translations/pl.ts export const pl { // ... existing translations errors: { // ... existing errors networkSync: Połączenie sieciowe nie powiodło się podczas synchronizacji, } } // sources/text/translations/es.ts export const es { // ... existing translations errors: { // ... existing errors networkSync: La conexión de red falló durante la sincronización, } }需要说明Happy 仓库中英文基准对象实际定义在 sources/text/_default.tsexport const en兼作类型源其余语言位于 sources/text/translations/ 目录index.ts统一汇总并校验结构一致性。译文落地后无需手动注册——类型系统自动让新 key 全局可用t(errors.networkSync) // Network connection failed during sync / Сбой сетевого подключения...九、质量检查清单子代理自带文档末尾附带了每轮翻译工作都必须逐项确认的检查清单这里完整保留Translation fits the UI context (button, header, description) —— 译文符合 UI 上下文按钮/标题/描述Consistent with existing terminology —— 与既有术语一致Appropriate tone for the context —— 语气与场景匹配Grammatically correct in target language —— 目标语言语法正确Cultural considerations addressed —— 文化适配已处理All language files updated —— 所有语言文件已更新Key naming follows project conventions —— key 命名遵循项目规范Parameters properly typed for dynamic strings —— 动态字符串参数类型正确十、实操总览新增一个可翻译字符串的完整链路结合以上全部内容在 Happy 应用中新增界面文案的推荐流程可归纳为触发子代理每当代码库引入新的用户可见文本新功能、新界面、修复缺失翻译时调用i18n-translator子代理上下文分析明确界面/组件、UI 元素类型、空间约束与语气并在common分区检索是否已有可复用译文在英文基准中定义在 sources/text/_default.ts 中按分区添加 key——静态文本用字符串常量动态文本用带类型参数的函数并利用plural辅助函数处理单复数同步其余语言为 sources/text/translations/ 下全部 10 种语言文件补上对应译文俄语/波兰语注意三种复数形式西班牙语采用中性表达技术术语保留原文交给类型系统验证index.ts的RecordSupportedLanguage, TranslationStructure会在编译期拒绝任何结构不一致的语言文件脚本复核运行 sources/scripts/compareTranslations.ts 生成完整性报告确认无 Missing / Untranslated / Extra代码中调用通过t(category.newKey)或t(category.newKey, { param: value })使用享受完整的 IntelliSense 与编译期参数校验。结语Happy 应用的 i18n 体系把「翻译」从游离的文案维护变成了类型约束下的工程实践对象化的翻译值、全语言的编译期结构校验、按语言实现的复数逻辑、以及一键生成的完整性报告共同构成了 i18n-translator 子代理落地的坚实基础。子代理文档本身则补充了工具与规范之外的关键一环——翻译的「人味」上下文分析、文化适配、语气拿捏。正如文档结尾所言Strive for translations that feel native, not translated追求母语般自然、而非翻译腔的译文——每个翻译都在塑造用户以母语体验产品的方式。延伸阅读i18n-translator 子代理定义Happy i18n 实现说明英文翻译基准与类型源i18n 入口与 t() 函数实现语言配置与支持列表俄语翻译三态复数示例波兰语翻译三态复数示例翻译完整性校验脚本【免费下载链接】happyMobile and Web client for Codex and Claude Code, with realtime voice, encryption and fully featured项目地址: https://gitcode.com/gh_mirrors/happy20/happy创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网