十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

OmniRoute 多语言国际化(i18n)工具链:翻译流水线、校验门禁与 CI 集成全解析

OmniRoute 多语言国际化(i18n)工具链:翻译流水线、校验门禁与 CI 集成全解析 OmniRoute 多语言国际化(i18n)工具链翻译流水线、校验门禁与 CI 集成全解析【免费下载链接】OmniRouteNever stop coding. Free MIT AI gateway: one endpoint, 352 providers (150 free), 1200 models Kimi, Claude, GPT, Gemini, GLM, DeepSeek, MiniMax. Works with Claude Code, Codex, Cursor, OpenCode, Cline Copilot. Quota-aware auto-fallback, RTKCaveman compression saves 15-95% tokens, MCP/A2A, Desktop/PWA. Built by 550 contributors项目地址: https://gitcode.com/GitHub_Trending/om/OmniRouteOmniRoute 的 i18n 体系覆盖仪表盘 UI 字符串、文档多语镜像与 RTL阿拉伯语/希伯来语布局三大面。本篇基于仓库中的 i18n 指南文档深入讲解其单一事实源 next-intl 运行时解析 自动翻译引擎 多层校验门禁的完整工具链读完后可独立掌握新增语言、批量翻译、翻译质量校验与 CI 集成的全套实操命令并能对照源码理解 locale 解析回退与占位符保护的底层实现。该文档位于 docs/i18n/phi/docs/guides/I18N.md是 docs/guides/I18N.md英文原版随文档翻译流水线生成的菲律宾语Filipino镜像两者内容同源。本文以该文档骨架为主体并对照当前仓库源码补充实现证据。1. 快速参考i18n 常用命令总览文档给出的命令速查表覆盖翻译生成、校验、QA 全流程任务命令生成翻译UI 字符串node scripts/i18n/generate-multilang.mjs messages翻译文档LLMpython3 scripts/i18n/i18n_autotranslate.py --api-url url --api-key key --model model校验某语言python3 scripts/i18n/validate_translation.py quick -l cs检查代码键python3 scripts/i18n/check_translations.py生成 QA 报告node scripts/i18n/generate-qa-checklist.mjs视觉 QAPlaywrightnode scripts/i18n/run-visual-qa.mjs说明原文档快照时期脚本位于scripts/顶层当前仓库中这些脚本已统一收纳至 scripts/i18n/ 目录如 validate_translation.py、check_translations.py、i18n_autotranslate.py上表已按当前仓库实际路径给出。此外当前仓库的 package.json 还注册了更推荐的 npm 脚本别名如i18n:run增量 LLM 文档翻译、i18n:check漂移检测门禁、i18n:sync-uiUI 键同步、i18n:add-locale一键新增语言详见第 4 节。2. 架构2.1 单一事实源Source of Truth文档声明的核心资产UI 字符串src/i18n/messages/en.json英文源约 2800 个键语言文件src/i18n/messages/{locale}.json各语言翻译框架next-intl基于 Cookie 的 locale 解析配置src/i18n/config.ts — 定义全部 locale、语言名与国旗从源码结构看当前仓库的声明层已进一步收敛src/i18n/config.ts 开头注释明确config/i18n.json才是 SOURCE OF TRUTH同时被文档翻译流水线消费config.ts只是thin typed adapter薄类型适配器禁止在其中手工维护语言清单。它从 config/i18n.json 读取并导出LOCALES、LANGUAGES、RTL_LOCALES、LOCALE_ALIASES与LOCALE_COOKIE NEXT_LOCALE见 src/i18n/config.ts。文档快照时期配置仍在config.ts内直接定义 30 个 locale当前仓库语言数量已显著扩展英文原版指南现声明支持 51 种语言。2.2 运行时流程Runtime Flow文档描述的 4 步运行时链路用户选择语言 → 写入NEXT_LOCALECookiesrc/i18n/request.ts 解析 localeCookie →Accept-Language/请求头 → 回退en动态import加载messages/{locale}.json组件使用useTranslations(namespace)与t(key)。request.ts 的实现与文档一致且有更完整的细节getRequestConfig先读NEXT_LOCALECookie第 125 行缺失时读x-locale请求头第 129 行再经resolveRequestedLocale(locale, LOCALES, LOCALE_ALIASES, DEFAULT_LOCALE)完成别名归一化第 132 行随后动态导入对应语言的 JSON 消息文件第 135 行。源码还实现了三层容错机制键级深合并回退deepMergeFallbackrequest.ts逐键将英文源合并进本地化文件且对__proto__/constructor/prototype等键做了原型污染防护__MISSING__:未翻译哨兵request.ts 导出PLACEHOLDER_PREFIX __MISSING__:当本地化文件中某键被同步脚本回填为该哨兵值时深合并会视其为不存在让干净的英文值胜出对应 issue #7258命名空间级浅合并request.ts当本地化文件缺少新命名空间如新增的cliCode、acpAgents等时按顶层命名空间整体回退到英文保证新功能在翻译补齐前仍可显示。2.3 支持的语言文档快照列出 30 个 locale当前仓库已扩展下表为文档原始清单phi即本文档所属的菲律宾语其 Google Translate 代码为tl代码语言RTLGoogle Translate 代码arالعربيةYesarbgБългарскиNobgcsČeštinaNocsdaDanskNodadeDeutschNodeesEspañolNoesfiSuomiNofifrFrançaisNofrheעבריתYesiwhiहिन्दीNohihuMagyarNohuidBahasa IndonesiaNoiditItalianoNoitja日本語Nojako한국어NokomsBahasa MelayuNomsnlNederlandsNonlnoNorskNonophiFilipinoNotlplPolskiNoplptPortuguês (Portugal)Noptpt-BRPortuguês (Brasil)NoptroRomânăNororuРусскийNoruskSlovenčinaNosksvSvenskaNosvthไทยNothtrTürkçeNotruk-UAУкраїнськаNoukviTiếng ViệtNovizh-CN中文 (简体)Nozh-CNRTL 处理在生成器中也有对应定义generate-multilang.mjs 中RTL_LOCALES new Set([ar, fa, he, ur])即 RTL 集合会随新语言如fa、ur的加入而同步扩展。3. 新增一种语言的完整步骤文档给出的 6 步流程第 1 步注册 Locale。文档当时的做法是编辑 src/i18n/config.ts// Add to LOCALES array xx, // Add to LANGUAGES array { code: xx, label: XX, name: Language Name, flag: ️ },第 2 步加入生成器。编辑 scripts/i18n/generate-multilang.mjs 的LOCALE_SPECS数组追加一条规格{ code: xx, googleTl: xx, label: XX, flag: ️, languageName: Language Name, readmeName: Language Name, docsName: Language Name, },该LOCALE_SPECS在源码中可完整看到generate-multilang.mjs每个条目携带code、googleTlGoogle 侧语言码如he对应iw、label、flag等字段分别服务于 UI 目录命名、翻译 API 调用与 README/文档镜像标题。第 3 步生成初始翻译。node scripts/i18n/generate-multilang.mjs messages会从en.json经 Google Translate 自动翻译生成src/i18n/messages/xx.json。第 4 步人工审校自动翻译。重点检查技术准确性、上下文术语、占位符{count}、{value}等的正确保留。第 5 步校验。python3 scripts/i18n/validate_translation.py quick -l xx python3 scripts/i18n/validate_translation.py diff common -l xx第 6 步生成翻译文档。node scripts/i18n/generate-multilang.mjs docs当前仓库的推荐做法一键 add-locale从源码结构看上述 6 步的手工流程已被 scripts/i18n/add-locale.mjs 自动化一条命令即可把新 locale 落到所有表面config、国旗、仪表盘目录、文档镜像、CLI 目录、README 与索引、语言条可选站点。结合英文原版指南docs/guides/I18N.md中的用法# 需要 .env 中配置 OMNIROUTE_TRANSLATION_API_URL / _API_KEY / _MODEL node scripts/i18n/add-locale.mjs --codeel --englishGreek --nativeΕλληνικά --flag # 预览模式 node scripts/i18n/add-locale.mjs --codeel --englishGreek --nativeΕλληνικά --flag --dry-run新增后需通过的语言面一致性校验包括i18n:check-ui-coverage、i18n:check-ratio真实翻译比例棘轮、check:docs-all与check:cli-i18n。对应 package.json 脚本为i18n:add-locale: node scripts/i18n/add-locale.mjs。4. 自动翻译流水线4.1 generate-multilang.mjsGoogle Translate 引擎文档将其定位为主自动翻译引擎用于 UI 字符串、README 与文档。用法node scripts/i18n/generate-multilang.mjs [messages|readme|docs|all]模式作用messages把en.json中缺失的键翻译进src/i18n/messages/{locale}.jsonreadme把README.md翻译为项目根目录下的README.{code}.mddocs把DOC_SOURCE_FILES翻译到docs/i18n/{locale}/{docName}all依次运行以上三种模式文档列出的关键特性均可在 generate-multilang.mjs 源码中逐一印证文本保护翻译前对代码块、行内代码、Markdown 链接/图片text、HTML 标签、表格与 ICU 占位符{count}、{value}、{total}等做掩码翻译后再还原——这是防止翻译 API 破坏技术内容的关键设计分块批处理用__OMNIROUTE_I18N_SEPARATOR__分隔符把多条字符串拼成一次请求以最小化 API 调用源码常量URL_MAX_TEXT_LENGTH 1800限定了单请求最大 1800 字符generate-multilang.mjs内存缓存TRANSLATION_CACHE new Map()避免同一会话内重复字符串的冗余调用重试逻辑针对 429/5xx 采用指数退避最多 5 次300ms × 次数超时REQUEST_TIMEOUT_MS 20000每请求 20 秒跳过已存在文件目标文件已存在时不覆盖保证人工修订不被自动翻译冲掉。重要行为文档特别强调docs/i18n/README.md每次运行重新生成——它是全部文档的自动索引根目录README.{code}.md仅在不存在时创建源码中EXISTING_README_CODES集合包含pt-BR、es、fr、it、ru、zh-CN、zh-TW、de等已有变体所有翻译文档中的语言条 **Languages:** ...会被自动插入/更新——本文档第 3 行那串多语导航链接即由该机制维护。现状提示当前源码文件头部已标注DEPRECATED 2026-05-13generate-multilang.mjs——docs模式已被基于 LLM 的run-translation.mjs取代并将于 v3.10 移除messages与readme模式因尚无替代而保留。4.2 i18n_autotranslate.pyLLM 辅助翻译次级翻译器——使用任意 OpenAI 兼容 LLM API包括 OmniRoute 自身来翻译docs/i18n/下已有的 Markdown 文件适合把 Google Translate 的初稿润色成更高质量的译文python3 scripts/i18n/i18n_autotranslate.py \ --api-url http://localhost:20128/v1 \ --api-key sk-your-key \ --model gpt-4o特性扫描docs/i18n/中的英文段落跳过代码块、表格与已翻译内容以技术翻译系统提示词发送段落给 LLM支持全部语言。4.3 当前推荐路径基于哈希的增量 LLM 翻译流水线从源码结构看scripts/i18n/run-translation.mjs、scripts/i18n/check-translation-drift.mjs仓库现主推的文档翻译路径是 package.json 中注册的 npm 脚本npm run i18n:run # 增量翻译仅触碰变更的源文件 npm run i18n:run -- --localept-BR # 限定单一语言 npm run i18n:run -- --filesCLAUDE.md,docs/architecture/ARCHITECTURE.md # 指定文件 npm run i18n:run -- --force # 强制全量重译 npm run i18n:check # CI 门禁状态漂移则非零退出配套机制后端由环境变量配置OMNIROUTE_TRANSLATION_API_URL/OMNIROUTE_TRANSLATION_API_KEY/OMNIROUTE_TRANSLATION_MODEL可选项OMNIROUTE_TRANSLATION_TIMEOUT_MS默认 60000、OMNIROUTE_TRANSLATION_CONCURRENCY默认 4写在.env中、绝不入库状态文件.i18n-state.json提交入库按源文件 × locale记录 SHA-256 哈希漂移检测完全确定性、不发 API 调用。UI 字符串的对应替代命令为npm run i18n:sync-ui -- --translate-markers --batch-size40。5. 校验与 QA5.1 validate_translation.py翻译校验器把任意 locale 的 JSON 与en.json对比并报告问题scripts/i18n/validate_translation.py约 635 行# 快速检查仅计数 python3 scripts/i18n/validate_translation.py quick -l cs # 输出 # Missing: 0 # Untranslated: 0 # Ignored (UNTRANSLATABLE_KEYS): 236 # 按命名空间的详细 diff python3 scripts/i18n/validate_translation.py diff common -l cs python3 scripts/i18n/validate_translation.py diff settings -l cs # 导出 CSV / Markdown python3 scripts/i18n/validate_translation.py csv -l cs report.csv python3 scripts/i18n/validate_translation.py md -l cs report.md # 完整报告默认 python3 scripts/i18n/validate_translation.py -l cs检测四类问题缺失键Missingen.json有而 locale 文件没有多余键Extralocale 文件有而en.json没有未翻译键Untranslatedlocale 值与英文源相同白名单除外占位符失配源与译文之间 ICU 占位符不一致。退出码供 CI 区分严重程度码含义0OK1通用错误2缺失字符串硬错误3未翻译警告软错误语言选择环境变量TRANSLATION_LANGcs或-l cs参数源码 validate_translation.py 中get_target_lang()的优先级为环境变量 → CLI 参数 → 默认cs向后兼容。5.2 check_translations.py代码-JSON 键校验器)扫描src/**/*.tsx与src/**/*.ts中的useTranslations()调用验证所有被引用的键存在于en.jsonscripts/i18n/check_translations.py# 基本检查 python3 scripts/i18n/check_translations.py # 详细输出 python3 scripts/i18n/check_translations.py --verbose # 自动修复把缺失键补进 en.json python3 scripts/i18n/check_translations.py --fix它与validate_translation.py互补后者保证翻译文件之间的键一致前者保证代码引用与 en.json之间不脱节。5.3 generate-qa-checklist.mjs静态分析 QA扫描 Next.js 页面文件的 i18n 风险指标并生成 Markdown 报告scripts/i18n/generate-qa-checklist.mjsnode scripts/i18n/generate-qa-checklist.mjs检查项固定宽度类溢出风险、方向性 left/right 类RTL 风险、易裁切模式、locale 键对等性相对en.json的缺失/多余、优先语言es、fr、de、ja、arREADME 语言选择条。输出docs/reports/i18n-qa-checklist-{date}.md。5.4 run-visual-qa.mjsPlaywright 视觉 QA在多种 locale 与视口下截取所有仪表盘路由截图并评估页面健康度scripts/i18n/run-visual-qa.mjs# 默认es, fr, de, ja, ar目标 localhost:20128 node scripts/i18n/run-visual-qa.mjs # 自定义 base URL 与语言 QA_BASE_URLhttp://staging.example.com QA_LOCALESde,fr node scripts/i18n/run-visual-qa.mjs # 自定义路由 QA_ROUTES/dashboard/settings,/dashboard/providers node scripts/i18n/run-visual-qa.mjs检测文本溢出、元素裁切、RTL 布局错位输出docs/reports/i18n-visual-qa-{date}.md与 JSON 报告。5.5 术语表一致性层仓库补充从源码结构看仓库在键对等与 ICU 校验之外还维护了一层术语表门禁scripts/i18n/glossary/ 下按 locale 存放反复出现概念provider、connection、routing、fallback、quota 等的canonical译法与synonyms列表捕获同一英文概念在不同字符串里被译成两个同样合法但互相冲突的词这类语义漂移protected-terms.json则强制产品/协议/环境变量名OmniRoute、OAuth、MCP、DATA_DIR等在译文值中原样出现。运行入口为 check-glossary-consistency.mjsnpm run i18n:check-glossary支持--locale/--json/--report参数。此外npm run i18n:check-ratiocheck-translation-ratio.mjs以与英文相同值/占位符比例作为真实翻译程度的棘轮指标。6. 管理不可翻译键untranslatable-keys.json文件scripts/i18n/untranslatable-keys.json白名单形式声明应保持与英文源完全一致的键供validate_translation.py避免对它们误报未翻译。结构如下{ description: Keys that should remain untranslated..., keys: [ common.model, common.oauth, health.cpu, ... ] }源码中加载逻辑位于 validate_translation.py启动时从外部 JSON 读取keys数组装入UNTRANSLATABLE_KEYS集合文件缺失时降级为空集。应放入白名单的内容类别文档归纳品牌/产品名landing.brandName、common.social-github技术术语/缩写health.cpu、mcpDashboard.pid、settings.aiICU/格式串apiManager.modelsCount、health.millisecondsShort占位值providers.openaiBaseUrlPlaceholder、cliTools.baseUrlPlaceholder协议名common.http、common.oauth、providers.oauth2Label导航区段名sidebar.primarySection、sidebar.cliSection新增键的方法编辑该文件的keys数组后重跑校验即可。注意它与术语表的protected-terms.json粒度不同前者按键路径把整键排除出对等/ICU 检查后者按概念检查任何译文值内部是否篡改了受保护名词。7. CI 集成CI 流水线中的 i18n 门禁文档描述的 CI 设计.github/workflows/ci.yml为三个协作的 jobi18n-matrixjob— 动态发现所有 locale 文件排除en.jsoni18njob— 对每个 locale 并行执行validate_translation.py quick -l langci-summaryjob— 把结果聚合成仪表盘摘要。# i18n-matrix: 发现语言 LANGS$(ls src/i18n/messages/*.json | xargs -n1 basename | sed s/.json$// | grep -v ^en$) # i18n: 逐语言校验 python3 scripts/i18n/validate_translation.py quick -l ${{ matrix.lang }}在当前的 ci.yml 中逐 locale 的validate_translation.py quick调用ci.yml与术语表门禁 jobi18n-glossary-zhcnci.yml均已确认存在摘要表会输出Languages checked / Total untranslated等指标形如## Translations | Metric | Value | |--------|------| | Languages checked | 30 | | Total untranslated | 0 | ✅ All translations complete8. 文件结构文档给出的目录全景按当前仓库实际布局整理脚本统一位于scripts/i18n/下src/i18n/ ├── config.ts # Locale 定义薄适配器读 config/i18n.json ├── request.ts # 运行时 locale 解析 三级回退合并 └── messages/ ├── en.json # 事实源约 2800 键 ├── cs.json # 捷克语翻译 ├── de.json # 德语翻译 └── ... # 全部 locale 文件 config/ └── i18n.json # 唯一 locale 声明处UI 文档 RTL 别名 scripts/i18n/ ├── generate-multilang.mjs # 自动翻译引擎Google Translate已标记弃用 ├── run-translation.mjs # 增量哈希 LLM 翻译当前主推 ├── i18n_autotranslate.py # LLM 文档翻译器 ├── add-locale.mjs # 一键新增语言 ├── validate_translation.py # 翻译校验器 ├── check_translations.py # 代码-JSON 键校验器 ├── check-translation-drift.mjs # 漂移检测i18n:check ├── check-translation-ratio.mjs # 真实翻译比例棘轮 ├── check-glossary-consistency.mjs # 术语表一致性 ├── generate-qa-checklist.mjs # 静态分析 QA ├── run-visual-qa.mjs # Playwright 视觉 QA ├── glossary/ # 分语言术语表 └── untranslatable-keys.json # 不可翻译键白名单 .github/workflows/ └── ci.yml # i18n 校验矩阵 术语表门禁 docs/ ├── guides/I18N.md # 英文原版 i18n 指南手写、持久 ├── i18n/ │ ├── README.md # 语言索引 │ ├── phi/ │ │ └── docs/guides/I18N.md # 本文件菲律宾语翻译镜像 │ ├── cs/、de/ ... # 各语言文档目录 └── reports/ ├── i18n-qa-checklist-*.md # 静态分析报告 └── i18n-visual-qa-*.md # 视觉 QA 报告9. 最佳实践编辑翻译时的工作流永远先编辑en.json—— 它是事实源运行翻译同步把新键传播到所有 locale文档时期为generate-multilang.mjs messages当前为npm run i18n:sync-ui审校自动译文—— 机器翻译只是起点而非终稿提交前校验——python3 scripts/i18n/validate_translation.py quick -l lang需要整键保留英文时更新untranslatable-keys.json。占位符安全ICU 占位符{count}、{value}、{total}、{seconds}必须原样保留复数格式{count, plural, one {# model} other {# models}}必须维持结构完整校验器会自动检测占位符失配无需人工比对。在代码中新增翻译键// 使用带命名空间的键 const t useTranslations(settings); t(cacheSettings); // 映射到 JSON 中的 settings.cacheSettings // 运行 check_translations.py 验证键存在 python3 scripts/i18n/check_translations.py --verboseRTL 注意事项阿拉伯语ar与希伯来语he是 RTL locale当前 RTL 集合已扩展至ar、fa、he、ur避免硬编码left/rightCSS —— 使用start/end逻辑属性视觉 QArun-visual-qa.mjs会捕获 RTL 布局错位。10. 已知问题与历史in.json→hi.json修复。生成器早期误用code: inGoogle Translate 的已弃用代码表示印地语而非正确的 ISO 639-1hi导致产生与hi.json重复的孤儿文件in.json。修复方式是把LOCALE_SPECS中code: in改为code: hi并删除孤儿文件该问题由上游提交952b0b22c引入。后续in又曾以Indonesian (Legacy)身份长期存在最终从所有表面移除id现声明aliases: [in]使旧的NEXT_LOCALEin或OMNIROUTE_LANGin解析到id——别名机制正由 config/i18n.json 的aliases字段驱动、经 src/i18n/config.ts 导出为LOCALE_ALIASES。docs/i18n/README.md曾为纯自动生成。文档快照时期该索引每次运行generate-multilang.mjs docs全量重生成手工编辑会丢失手写内容应放在docs/guides/I18N.md。从源码演进看当前它已改为手工维护add-locale.mjs只做行内插入新 locale 行与更新计数句双向一致性由单测tests/unit/i18n-locale-surfaces-parity.test.ts守护配置了文档 locale 就必须有索引行索引行必须能映射回已配置 locale。不可翻译键白名单外置。untranslatable-keys.json白名单从validate_translation.py内的内联 Python 集合迁移为外部 JSON 文件以便维护校验器运行时加载源码 validate_translation.py 可确认。quick 检查的 Ignored 计数。quick模式现会输出被untranslatable-keys.json忽略的键数量让未翻译计数与有意不译计数分离、互不干扰Missing: 0 Untranslated: 0 Ignored (UNTRANSLATABLE_KEYS): 23611. 小结OmniRoute 的 i18n 工具链呈现清晰的四层结构声明层config/i18n.json→src/i18n/config.ts薄适配器、运行时层next-intl Cookie 解析 键级/哨兵/命名空间三级回退合并见 src/i18n/request.ts、生产层Google Translate 批量引擎与 LLM 增量引擎双轨文本掩码、分块批处理与哈希状态保证可重复性、质量层键对等校验、占位符检测、术语表一致性、静态/视觉 QA 与 CI 矩阵门禁。对维护者而言最重要的纪律是先改en.json、同步后必校验、占位符零容忍、整键保留英文走白名单——这套规则由前述脚本与 CI 共同强制执行。【免费下载链接】OmniRouteNever stop coding. Free MIT AI gateway: one endpoint, 352 providers (150 free), 1200 models Kimi, Claude, GPT, Gemini, GLM, DeepSeek, MiniMax. Works with Claude Code, Codex, Cursor, OpenCode, Cline Copilot. Quota-aware auto-fallback, RTKCaveman compression saves 15-95% tokens, MCP/A2A, Desktop/PWA. Built by 550 contributors项目地址: https://gitcode.com/GitHub_Trending/om/OmniRoute创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表