replexica new-compiler 翻译 API 实战指南:Translator 接口、批处理翻译与 Server Components 集成

replexica new-compiler 翻译 API 实战指南:Translator 接口、批处理翻译与 Server Components 集成 replexica new-compiler 翻译 API 实战指南Translator 接口、批处理翻译与 Server Components 集成【免费下载链接】replexicaOpen-source localization engineering tools. Connects to Lingo.dev localization engineering platform for consistent, quality translations.项目地址: https://gitcode.com/GitHub_Trending/re/replexica本篇指南基于 replexica 仓库中packages/new-compiler即lingo.dev/compiler的翻译模块使用文档展开系统讲解重构后的Translator接口模型如何使用PseudoTranslator做免 API 的伪本地化测试、如何用LingoTranslator接入 Lingo.dev 引擎或自定义 LLM 提供商完成真实 AI 翻译、如何为任意翻译器叠加磁盘缓存以及在 React Server Components 中通过预加载、运行时翻译和开发翻译服务器三种方式消费翻译结果。读完本文你将掌握这套统一翻译 API 的完整调用链、配置细节与源码级实现原理能够直接在自己的 Next.js/React 项目中落地。一、统一的Translator接口重构后的核心抽象翻译模块重构后所有翻译组件伪翻译器、AI 翻译器、自定义翻译器都遵循同一个接口契约。该接口定义在 api.ts 中export type TranslatableEntry { text: string; context: Recordstring, any }; export interface TranslatorConfig { config: Config; translate: ( locale: LocaleCode, entriesMap: Recordstring, TranslatableEntry, ) PromiseRecordstring, string; }接口有三个要点泛型Config每个翻译器持有自己的配置对象通过只读属性config暴露。LingoTranslator的配置是LingoTranslatorConfig包含models、sourceLocale、prompt、aiTimeoutPseudoTranslator的配置是PseudoTranslatorConfig包含delayMedian。批处理能力translate()接收Recordstring, TranslatableEntry——即hash → 可翻译条目的映射一次调用可以翻译一条或多条。TranslatableEntry由text原文和context上下文元数据组成。扁平返回返回Recordstring, string即hash → 译文的映射调用方可以按 hash 直接取译文无需遍历嵌套结构。与Translator接口配套的还有两个核心类型DictionarySchema翻译字典的扁平结构含version、locale、entries字段和PartialTranslationError。后者用于部分失败场景——当一次翻译运行中途失败时会把已经成功返回的条目随异常一并带出避免下次构建重新为相同源文本付费见 api.ts 中的注释说明。所有公共类型与实现都从 index.ts 统一导出// Core API export type { Translator, TranslatableEntry } from ./api; // Translators export { PseudoTranslator } from ./pseudotranslator; export { LingoTranslator } from ./lingo; export type { LingoTranslatorConfig } from ./lingo; // Translation Service (orchestrator) export { TranslationService } from ./translation-service; // Cache abstractions export type { TranslationCache, LocalCacheConfig } from ./cache; export { createCache } from ./cache-factory;二、PseudoTranslator零成本伪本地化测试在开发与测试阶段如果不想消耗真实翻译 API 的配额可以使用伪翻译器。文档给出的用法如下import { PseudoTranslator } from lingo.dev/compiler-beta/translate; const translator new PseudoTranslator({}); // 单条翻译 const result await translator.translate(es, { temp: { text: Hello World, context: {} }, }); // 输出: { temp: es/Ĥéĺĺó Ŵóŕĺḍ } // 多条翻译 const batch await translator.translate(fr, { hash1: { text: Dashboard, context: {} }, hash2: { text: Settings, context: {} }, }); // 输出: { hash1: fr/Ḍáśĥḅóáŕḍ , hash2: fr/Śéţţíñĝś }从源码实现看pseudotranslator/index.ts 的机制非常精巧字符映射替换内置PSEUDO_MAP将每个 ASCII 字母映射为带变音符的字母如H→Ĥ、e→é模拟真实语言的字符扩展。长度膨胀约 30%输出末尾追加Math.ceil(text.length * 0.3)个空格用于测试界面布局在长文本下的表现这正是伪本地化pseudolocalization的核心价值——提前暴露文本截断、换行错乱等 i18n 布局问题。占位符与组件标签保护正则/(\{\w}|\/?\w\/?)/g匹配{varName}形式的变量占位符和a0、/a0形式的组件标签这些片段原样保留、不做字符替换确保伪翻译不会破坏插值语法。可选延迟模拟PseudoTranslatorConfig.delayMedian可配置中位延迟实现会在median ± 50%区间内随机生成延迟delayMedian: 0时不延迟用于模拟真实 API 的响应节奏。输出格式为${locale}/${pseudolocalize(text)}前缀带上目标语言代码方便肉眼识别这条字符串来自哪个语言的伪翻译。三、LingoTranslator真实 AI 翻译的生产级翻译器生产环境使用LingoTranslator。文档提供了两种配置形态import { lingoTranslator } from lingo.dev/compiler-beta/translate; // 使用 Lingo.dev Engine const translator new lingoTranslator({ models: lingo.dev, sourceLocale: en, }); // 使用自定义 LLM 提供商 const customTranslator new lingoTranslator({ models: { en:es: google:gemini-2.0-flash, en:fr: groq:llama3-70b-8192, *:*: openrouter:anthropic/claude-3.5-sonnet, }, sourceLocale: en, prompt: Translate professionally for software UI, }); // 翻译 const result await translator.translate(es, { hash1: { text: Welcome, context: {} }, hash2: { text: Sign In, context: {} }, });注意文档中示例写作lingoTranslator当前源码中的实际类名是LingoTranslator见 lingo/translator.ts两者是同一实现的命名变体以你当前安装的包版本导出为准。3.1 两种 models 模式LingoTranslatorConfig.models支持两种取值lingo/translator.tslingo.dev走 Lingo.dev 引擎通过LingoDotDevEngine.localizeObject()完成翻译适合不想自己管理 LLM 提供商与提示词的场景。Recordstring, string按语言对 → provider:model映射指定模型例如en:es: google:gemini-2.0-flash表示从英文翻译到西班牙文时使用 Gemini。3.2 语言对模型的匹配优先级当使用映射模式时model-factory.ts 中的getLocaleModel()会按以下优先级匹配模型${sourceLocale}:${targetLocale}精确语言对如en:es*:${targetLocale}任意源语言 → 指定目标语言${sourceLocale}:*指定源语言 → 任意目标语言*:*兜底任意语言对模型字符串格式为provider:model解析时只在第一个冒号处切分因此模型名内部可以包含冒号parseModelString的实现见 model-factory.ts。3.3 底层翻译流程LingoTranslator.translate()的完整调用链体现了生产级设计的几个关键环节lingo/translator.ts字典化先把entriesMap转成DictionarySchemadictionaryFrom()构造version字段当前固定为 0.1源码注释中标注了后续与 hash 函数版本联动的计划。分块chunkingchunkDictionary()按每块最多100 条拆分字典避免单次请求上下文过大。逐块翻译每个 chunk 单独调用 LLM翻译完成后再由mergeDictionaries()合并。部分失败保护若中途抛错translateDictionary()会抛出携带已译条目的PartialTranslationError上层如TranslationService可据此保留已付费的翻译结果。超时兜底所有 AI 调用都包在withTimeout()中超时上限取config.aiTimeout ?? DEFAULT_TIMEOUTS.AI_API防止模型无响应导致构建无限挂起。LLM 分支的具体请求构造lingo/translator.ts值得注意系统提示词由getSystemPrompt()生成包含sourceLocale、targetLocale和自定义prompt随后注入若干组 few-shot 示例shots.flatMap生成 user/assistant 交替消息最后把源字典经obj2xml()序列化为 XML 作为用户消息响应文本再由parseXmlFromResponseText()解析回DictionarySchema。也就是说翻译请求与响应都通过 XML 结构在模型与代码之间传递。四、缓存createCache与磁盘缓存实现文档中Adding Caching一节展示的是用createCachedTranslator包装翻译器import { lingoTranslator, createCachedTranslator, } from lingo.dev/compiler-beta/translate; const translator new lingoTranslator({ models: lingo.dev, sourceLocale: en, }); // 添加磁盘缓存 const cachedTranslator createCachedTranslator(translator, { cacheDir: .lingo, sourceRoot: ./app, }); // 第一次调用触发真实翻译 await cachedTranslator.translate(es, entriesMap); // 第二次调用直接命中缓存速度极快 await cachedTranslator.translate(es, entriesMap);在当前的编译器源码中缓存抽象对应的是TranslationCache接口与createCache工厂cache.ts、cache-factory.ts。TranslationCache接口定义了完整的生命周期方法get(locale)/get(locale, hashes)按语言取缓存可只取指定 hash 子集update(locale, translations)合并式更新不覆盖已有内容set(locale, translations)整体替换has(locale)/clear(locale)/clearAll()存在性检查与清理。默认且当前唯一支持的实现是LocalTranslationCachelocal-cache.ts存储位置cacheDir/locale.json即文档与 README 中描述的.lingo/cache/{locale}.json写入格式dictionaryFrom(locale, translations)序列化的 JSON含version、locale、entries格式化为两空格缩进便于人工检查IO 超时所有文件读写都包在withTimeout(..., DEFAULT_TIMEOUTS.FILE_IO)中防止文件系统卡死目录自动创建写入前fs.mkdir(cacheDir, { recursive: true })无需手动建目录。4.1 缓存与翻译的自动编排TranslationService如果你希望缓存判断、覆盖值overrides、复数处理与翻译失败恢复由框架自动完成可以使用TranslationServicetranslation-service.ts。它的translate()编排了完整的 8 步流程确定工作 hash 集默认取 metadata 的全部键先查缓存得到已缓存译文过滤出未缓存的 hash从 metadata 中筛选未缓存条目若配置了pluralization先对未缓存条目做复数处理分离出带overrides[locale]覆盖值的条目直接采用不翻译对真正需要翻译的条目调用底层translator.translate()源语言则直接返回sourceText合并缓存与新增译文、写入缓存、汇总statstotal/cached/translated/failed与逐条errors。TranslationService还内置了开发模式回退策略当environment development且dev.usePseudotranslator开启时直接用内存缓存的伪翻译器若真实翻译器创建失败如缺少 API Key开发模式自动回退到PseudoTranslator并告警生产模式则直接抛错——这保证了开发流程永远不会被缺 Key 卡死。五、在 React Server Components 中使用文档给出了三种在 Server Components 中消费翻译的选项三者都通过getServerTranslations实现见 server-only/index.ts获得t函数。选项 1预加载翻译推荐构建期把metadata.json与各语言缓存文件随包导入运行时零网络调用import { getServerTranslations } from lingo.dev/compiler-beta/react/server; import metadata from ./.lingo/metadata.json; import esTranslations from ./.lingo/cache/es.json; export default async function Page() { const t await getServerTranslations({ metadata, locale: es, sourceLocale: en, translations: extractTranslations(esTranslations), // 扁平 hash - 译文映射 }); return h1{t(hash123)}/h1; }选项 2使用 Translator运行时按需翻译把缓存包装后的翻译器传给getServerTranslations未命中缓存的 hash 会在运行时实时翻译import { getServerTranslations } from lingo.dev/compiler-beta/react/server; import { lingoTranslator, createCachedTranslator } from lingo.dev/compiler-beta/translate; import metadata from ./.lingo/metadata.json; const translator createCachedTranslator( new lingoTranslator({ models: lingo.dev, sourceLocale: en, }), { cacheDir: .lingo, sourceRoot: ./app, } ); export default async function Page() { const t await getServerTranslations({ metadata, locale: es, sourceLocale: en, translator, // 按需翻译 }); return h1{t(hash123)}/h1; }选项 3翻译服务器开发模式只传 metadata 与语言由开发期的 Translation Server 提供翻译组件代码最简洁import { getServerTranslations } from lingo.dev/compiler-beta/react/server; import metadata from ./.lingo/metadata.json; export default async function Page() { const t await getServerTranslations({ metadata, locale: es, sourceLocale: en, }); return h1{t(hash123)}/h1; }5.1 服务端翻译的底层获取逻辑从源码看getServerTranslations不直接调用翻译器而是委托给 server-only/translations.ts 中的fetchTranslationsOnServer()开发模式若配置了serverUrl优先请求开发翻译服务器fetchFromDevServer失败则回退文件系统生产模式或开发回退从文件系统读取依次尝试.lingo/cache/{locale}.json与.next/{locale}.json两个常见路径解析出entries作为扁平译文映射t函数行为t(hash, sourceText, params?)在translations[hash]缺失时回退到sourceText传入params时通过renderRichText渲染富文本。另外注意Server Components 中还有一个更贴合编译器工作流的useTranslation钩子server/useTranslation.ts它利用 React 的use()在不写 async/await的情况下消费 promise且与客户端版本签名完全一致实现了组件的同构isomorphic——编译器会在构建期把组件内使用的 hash 列表注入进来。六、编写自定义 Translator实现Translator接口即可接入整个缓存与编排体系import type { Translator, TranslatableEntry, } from lingo.dev/compiler-beta/translate; class MyCustomTranslator implements TranslatorMyConfig { constructor(readonly config: MyConfig) {} async translate( locale: LocaleCode, entriesMap: Recordstring, TranslatableEntry, ): PromiseRecordstring, string { // 批量翻译多条条目 const results: Recordstring, string {}; for (const [hash, entry] of Object.entries(entriesMap)) { results[hash] await myTranslationService(entry.text, locale); } return results; } } // 使用它 const translator new MyCustomTranslator({ apiKey: ... }); const cachedTranslator createCachedTranslator(translator, { cacheDir: .lingo, });自定义翻译器的三个约束与建议构造函数持有配置通过readonly config保存配置实例供外部读取与调试保持批处理语义translate()必须完整返回entriesMap中所有 key 的译文若实现为逐条循环如示例所示注意这是文档演示写法生产环境应优先并行或走真实 AI 批处理以控制成本参考LingoTranslator的 100 条分块策略可组合性自定义翻译器同样可以被缓存包装器包裹缓存层与翻译实现完全解耦。七、从旧 API 迁移重构前的翻译函数是一个裸的TranslateFunction把模型、源字典、语言对、提示词全部作为参数传入// 重构前TranslateFunction const translateFn: TranslateFunction async ( models, sourceDictionary, sourceLocale, targetLocale, prompt, ) { // 翻译逻辑 return translatedDictionary; }; const cached createCachedTranslator(translateFn, cacheConfig);重构后改为实例化翻译器对象配置内聚到实例中// 重构后Translator 接口 const translator new lingoTranslator({ models, sourceLocale, prompt, }); const cached createCachedTranslator(translator, cacheConfig);迁移要点原来散落的 5 个位置参数收敛为models、sourceLocale、prompt三个配置字段外加aiTimeout语言对改为translate(locale, entriesMap)的方法调用形态缓存包装的输入从函数变成实例但包装器 API 形态保持一致迁移成本集中在翻译逻辑的封装方式上。八、重构收益文档总结了本次重构带来的六个核心收益结合源码可以进一步印证类型安全Type SafetyTranslatorConfig泛型接口让每个翻译器的配置类型在编译期即被约束LingoTranslatorConfig、PseudoTranslatorConfig各自独立lingo/translator.ts、pseudotranslator/index.ts一致性Consistency所有翻译器伪翻译、Lingo.dev、自定义遵循同一translate(locale, entriesMap)签名TranslationService无需感知具体实现即可编排translation-service.ts可组合性Composability翻译器可自由包裹缓存、超时、日志等增强层状态管理State Management配置与翻译逻辑内聚于实例避免函数式 API 的参数漂移可测试性Testing伪翻译器与内存缓存让测试无需真实 API Key仓库中 pseudotranslator/index.test.ts、lingo/translator.test.ts、translation-service.test.ts 均以此为基础统一缓存CachingTranslationCache抽象磁盘LocalTranslationCache、内存MemoryTranslationCache对所有翻译器一视同仁缓存命中逻辑集中在TranslationService一处。九、环境变量与 API Key使用LingoTranslator前必须配置对应提供商的 API Keymodel-factory.ts 中的providerDetails表完整登记了各提供商的环境变量名# 推荐Lingo.dev 引擎 LINGODOTDEV_API_KEYyour_key_here # 或直接对接 LLM 提供商 GOOGLE_API_KEYyour_key_here GROQ_API_KEYyour_key_here OPENROUTER_API_KEYyour_key_here MISTRAL_API_KEYyour_key_here # 其他受支持提供商 OPENAI_API_KEYyour_key_here ANTHROPIC_API_KEYyour_key_here # Ollama 本地模型无需 API Key几个关键行为值得注意Key 读取顺序getKeyFromEnv()先读process.env再依次尝试从项目根目录的.env、.env.local、.env.development加载使用 dotenv启动期一次性验证LingoTranslator构造函数即调用validateAndGetApiKeys()按配置解析出所需的全部提供商并校验 Key缺失时抛出带明确提示的错误当models: lingo.dev时只校验LINGODOTDEV_API_KEY映射模式则按模型中出现的 provider 集合逐一校验OpenAI 兼容端点通过OPENAI_BASE_URL可为 OpenAI 提供商自定义 base URL兼容 Nebius 等第三方 OpenAI 兼容服务未知提供商保护validateAndGetApiKeys会对未知 provider 抛出错误并列出受支持的提供商列表。十、完整示例缓存翻译器 RootLayout把以上全部能力组合成一个可运行的完整示例文档原文// translator.ts import { LingoTranslator, createCachedTranslator, } from lingo.dev/compiler-beta/translate; export const translator createCachedTranslator( new LingoTranslator({ models: lingo.dev, sourceLocale: en, }), { cacheDir: .lingo, sourceRoot: ./app, } ); // app/layout.tsx import { getServerTranslations } from lingo.dev/compiler-beta/react/server; import { translator } from ./translator; import metadata from ./.lingo/metadata.json; export default async function RootLayout({ children }) { const t await getServerTranslations({ metadata, translator, }); return ( html body nav a href/{t(home_link)}/a a href/about{t(about_link)}/a /nav {children} /body /html ); }运行流程拆解首次渲染时translator.translate(es, entriesMap)调用 Lingo.dev 引擎翻译结果写入./app/.lingo/cache/es.json后续渲染或重新构建时缓存层先命中翻译请求被跳过磁盘缓存的合并更新逻辑见 local-cache.ts 的update()getServerTranslations在生产模式直接从.lingo/cache/{locale}.json读取server-only/translations.ts开发模式则优先走 Translation Server 热更新。十一、进一步阅读模块导出总览translators/index.ts 与 translators/README.md含translator: pseudo的配置式伪翻译、缓存目录结构说明接口与异常定义translators/api.ts生产翻译器实现translators/lingo/translator.ts分块、超时、XML 往返提供商注册与 Key 校验translators/lingo/model-factory.ts缓存抽象与实现translators/cache.ts、translators/local-cache.ts、translators/cache-factory.ts翻译编排器translators/translation-service.tsServer Components 集成react/server-only/index.ts、react/server/useTranslation.ts、react/server-only/translations.ts包导出配置new-compiler/package.jsonlingo.dev/compiler的./react/server、./react/next等条件导出说明文档示例中的lingoTranslator、createCachedTranslator与当前源码中的LingoTranslator、createCache/TranslationCache为同一抽象的不同命名/封装形态具体导入名以你使用的lingo.dev/compiler版本为准Translator接口本身configtranslate(locale, entriesMap)是各版本一致的核心契约。【免费下载链接】replexicaOpen-source localization engineering tools. Connects to Lingo.dev localization engineering platform for consistent, quality translations.项目地址: https://gitcode.com/GitHub_Trending/re/replexica创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考