ARTICLE DETAIL

资讯详情

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

Lingo.dev Compiler 变更日志全解析:从 0.1.0 到 0.12.13 的架构演进、多 Provider 支持与供应链安全加固实践

Lingo.dev Compiler 变更日志全解析:从 0.1.0 到 0.12.13 的架构演进、多 Provider 支持与供应链安全加固实践 Lingo.dev Compiler 变更日志全解析从 0.1.0 到 0.12.13 的架构演进、多 Provider 支持与供应链安全加固实践【免费下载链接】replexicaOpen-source localization engineering tools. Connects to Lingo.dev localization engineering platform for consistent, quality translations.项目地址: https://gitcode.com/GitHub_Trending/re/replexica本文以packages/compiler/CHANGELOG.md记录为主线结合packages/compiler/src下源码实现系统梳理 Lingo.dev 本地化编译器lingo.dev/_compiler从诞生到弃用的完整版本演进史。读者将掌握该编译器的核心架构unplugin 插件体系、Babel AST 转换、LLM 驱动翻译管线、可配置参数与 API Key 解析优先级理解 Turbopack/Next.js 适配、七大 LLM Provider 接入方式以及贯穿 0.12.x 系列的依赖供应链安全加固方法论并最终获得迁移至新一代编译器lingo.dev/compiler的完整路径。一、编译器是什么一个把翻译搬进构建管线的 unpluginlingo.dev/_compiler源码位于 packages/compiler是 Lingo.dev 生态中的本地化编译器。它与普通 i18n 方案的根本区别在于不需要手动编写翻译键值对而是直接扫描你的 JSX/TSX 源码把组件内的可翻译文本提取出来调用 LLM大语言模型翻译成目标语言再把翻译结果回写到构建产物中。从 入口文件 可以看到整个编译器基于unplugin的createUnplugin构建因此同一套逻辑可以被注入到 Webpack、Vite、Turbopack 等不同构建体系loadInclude匹配字典文件LCP_DICTIONARY_FILE_NAME将lingo目录下的字典 JSON 作为模块加载transformInclude匹配.tsx/.jsx文件enforce: pre在 Babel 解析阶段之前介入通过transformComponent完成文本提取与替换在非 CI/Docker 环境下启动时会校验models配置对应的 LLM API Key 是否就绪见 validateLLMKeyDetails缺失时直接抛出带指引的错误。编译器对外暴露两个入口lingoCompiler.next({...})(nextConfig)与lingoCompiler.vite({...})(viteConfig)见 index.ts。其中next()内部还会根据turbopack.enabled默认auto即读取TURBOPACK1环境变量自动选择注入 Webpack 插件还是 Turbopack loader 规则**/*.{ts,tsx,js,jsx}→lingo-turbopack-loader.cjs这也是 0.4.0 Add support for Next.js Turbopack 与 0.7.5 support Turbopack in Next.js v14 两个里程碑的落地点。二、核心配置参数从默认值到类型约束编译器的全部参数定义在 _base.tsdefaultParams即各参数的默认值。这是阅读变更日志尤其是各版本improve type safety of compiler params、support custom prompts等条目时最直接的对照表参数类型默认值说明sourceLocaleLocaleCodeISO 639-1 / BCP 47en源语言targetLocalesLocaleCode[][es]目标语言数组lingoDirstringlingo翻译文件存放目录相对sourceRootsourceRootstringsrc待翻译源码目录相对工作目录rscbooleanfalse是否生成 React Server Components 代码Next.js 恒为trueVite 恒为falseuseDirectivebooleanfalse是否只处理带use i18n;指令的文件debugbooleanfalse是否输出额外调试日志modelslingo.dev \| ModelMap{}翻译引擎lingo.dev走官方引擎或 locale→模型映射promptstring \| nullnull自定义 system prompt仅对自定义模型生效models的映射语法采用源语言:目标语言: provider:model形式支持*通配符例如{ en:es: openai:gpt-3.5-turbo }。类型定义ModelMap 系列类型在 0.6.0 被重构为模板字面量类型把LocalePair、AnyTargetLocale、AnyLocale等模式收敛为编译期可检查的类型——这正是变更日志中 improve type safety of compiler params 的具体含义。三、版本演进时间线四个阶段的架构变迁把 0.1.0 → 0.12.13 的五十余条记录按主题聚类可以清晰看到这款编译器的成长脉络。3.1 0.1.x 起步期核心管线与工程细节打磨0.1.0 added the compiler 确立包的存在。随后一序列 patch 版本解决的都是让编译管线在不同环境里稳定跑起来的工程问题性能优化0.1.2 移除cloneDeep以减少字典拷贝开销0.1.7 将插件unshift到插件列表最前保证最先参与转换0.1.3 改为扁平化 re-export跨平台兼容0.1.8 支持 Windows 上的filePath、0.1.9 规范化字典路径、0.1.10 修复 Windows 下触发页面热重载的机制字典合并0.1.6 引入merge dictionaries能力为后续多文件、多 chunk 的翻译结果合并奠定基础错误处理与边界0.1.5 修复value.trim()空值问题、0.1.12 处理lingo目录被删除的异常、0.1.13 跳过对LingoProvider组件的解析并改进 Groq API 错误处理。3.2 0.2.x – 0.5.xProvider 生态与构建体系扩展这一阶段编译器从仅支持单一 LLM走向多 Provider 可插拔0.2.0实现 Google AIGeminiProvider0.2.1API Key 支持从环境变量与.env文件读取详见第五节0.3.0一次大版本引入 Ollama 本地模型、OpenRouter 聚合平台同时improved compiler concurrency, caching, added lingo.dev engine to the compiler——即把官方lingo.dev引擎接入并优化了并发与缓存0.3.1/0.3.2/0.3.3连续三轮修复字典合并dictionary merging逻辑0.4.0支持 Next.js Turbopack0.5.0新增 Mistral AI官方用法为设置MISTRAL_API_KEY或执行npx lingo.devlatest config set llm.mistralApiKey key支持ai-sdk/mistral暴露的全部 Mistral 模型0.5.4支持自定义 prompt即CompilerParams.prompt覆盖默认 system prompt仅对自定义模型生效。3.3 0.6.x – 0.9.xJSX 处理健壮性与供应链安全开端随着接入的项目变多编译器开始修复大量 AST 转换层的边界问题0.7.0 Whitespace Normalization改进normalizeJsxWhitespace在保留 JSX 元素内部前导空格的同时清除格式化产生的多余空白与空行并确保{ }这类显式空格不会产生双空格配套测试见 jsx-content-whitespace.spec.ts0.7.1 / 0.7.4修复 type-only React 导入、import * as React命名空间导入与默认导入的处理0.7.6防止重复 props 注入0.7.7修正字典路径计算0.7.13修复正则替换0.7.15编译器从直接退出进程改为抛出异常让父应用CLI、CI 脚本可以优雅捕获——这是可观测性与健壮性的重要转折0.8.0将所有依赖钉死到精确版本去掉^/~范围杜绝供应链攻击面所有依赖升级都必须显式评审0.9.0编译器与 CLI 全面升级到 AI SDK v5。3.4 0.10.x – 0.12.x开放生态与安全加固收官0.10.0支持任意 OpenAI 兼容 Provider文档举例 Nebius通过OPENAI_BASE_URL环境变量指向自建或第三方兼容端点0.10.1发布弃用警告——从这一版起lingo.dev/_compiler被标记为 legacy新增运行时next()/vite()/Turbopack loader 弃用提示、全部公共 API 的deprecatedJSDoc 标签并指引迁移到lingo.dev/compiler详见第七节0.11.0/0.11.1将zod移入 external dependencies 深度减小打包体积与版本冲突0.11.4发送给 PostHog 的distinct_id改为邮箱哈希值强化用户隐私0.12.0SDK 与 CLI 迁移到统一 API 端点——所有请求统一走api.lingo.dev并以X-API-Key请求头鉴权同时新增engineId配置项可自动从旧vNext配置迁移0.12.x 系列连续数版依赖安全加固详见第六节。四、翻译管线源码级原理分块、XML 序列化与模型路由变更日志里反复出现的 dictionary merging、concurrency、chunk 都对应 lib/lcp/api/index.ts 中LCPAPI类的实现。整条翻译管线可以拆成四步字典分块_chunkDictionary以MAX_ENTRIES_PER_CHUNK 100为上限把整本字典按文件、按条目切成多个 chunk避免单次 LLM 调用上下文过长这也是 0.3.0 improved compiler concurrency 得以并行的基础分块翻译_translateChunk若models lingo.dev走LingoDotDevEngine.localizeObject()调用官方引擎否则从models映射中解析出provider:model用generateText发起 LLM 请求XML 中间格式obj2xml/xml2obj自定义 LLM 模式下字典会被序列化为结构化的object/array/valueXML 发给模型模型返回的 XML 再解析回字典对象。该格式转换实现在 xml2obj.ts基于fast-xml-parser这也是 0.12.7 将其升级到 5.7.0 的原因结果合并_mergeDictionaries把多个 chunk 的翻译结果按文件 key 用_.merge合并回完整字典——对应 0.3.1/0.3.2/0.3.3 反复修复的 dictionary merging。模型路由在_createAiModelindex.ts中通过switch完成目前支持groq、google、openrouter、ollama、mistral、openai、anthropic七个 Provider分别对应ai-sdk/*或ollama-ai-provider-v2的工厂函数未识别的 Provider 会抛出明确错误。各 Provider 的展示名、环境变量名、配置键名统一登记在 provider-details.tsProvider环境变量用户级配置键npx lingo.dev config set备注GroqGROQ_API_KEYllm.groqApiKey0.1.4 起从.env读取GoogleGOOGLE_API_KEYllm.googleApiKey0.2.0 引入OpenAIOPENAI_API_KEYllm.openaiApiKey兼容OPENAI_BASE_URL自定义端点AnthropicANTHROPIC_API_KEYllm.anthropicApiKey—OpenRouterOPENROUTER_API_KEYllm.openrouterApiKey0.3.0 引入Ollama无需 Key无需 Key0.3.0 引入本地模型MistralMISTRAL_API_KEYllm.mistralApiKey0.5.0 引入Lingo.dev EngineLINGODOTDEV_API_KEYauth.apiKey官方托管引擎五、API Key 解析优先级环境变量 .env 用户级配置0.2.1 load API key from env var and env files 定义并沿用至今的 Key 查找规则实现集中在 llm-api-key.ts环境变量优先process.env[VAR]命中即返回.env文件兜底通过dotenv.config()依次读取项目根目录的.env、.env.local、.env.development用户级配置读取.lingodotdevrc中的llm.*/auth.apiKey键getKeyFromRc经 lodash_.get取值。最终取值逻辑形如getGroqKey() getGroqKeyFromEnv() || getGroqKeyFromRc()。在 CI/Docker 环境isRunningInCIOrDocker中还会做更严格的校验lingo.dev引擎模式下必须存在LINGODOTDEV_API_KEY否则报错并提示在流水线环境变量中配置。启动时的validateLLMKeyDetails会友好打印Key 从哪里发现同时存在于 env 与 rc 时明确提示环境变量优先级更高。六、安全加固专题0.12.x 系列的三层防御0.12.x 是变更日志中安全密度最高的阶段可以归纳为三层防御策略仓库级依赖治理0.12.8根pnpm overrides对 axios、vite、ws、form-data、fast-xml-parser、shell-quote、lodash、serialize-javascript、minimatch、picomatch、tmp 等传递依赖统一钉到已修复版本把pnpm audit从121 个 high 5 个 critical 归零发布包消费者保护0.12.7 / 0.12.8 / 0.12.11把随发布包分发出去的运行时依赖也升级到修复版本例如lodash 4.17.23 → 4.18.1、ws 8.18.3 → 8.21.0、modelcontextprotocol/sdk 1.22.0 → 1.26.0、fast-xml-parser 5.7.0、js-cookie 3.0.8、minimatch 10.2.5并用overrides钉住 picomatch、qs、postcss、ajv、launch-editor、js-yaml、joi 等变更日志还特别解释了js-cookie选 3.0.8 而非 3.0.73.0.7 意外把 Node 引擎要求抬到 20破坏 ES5 兼容与 Node 18 支持以及lodash选 4.17.23 而非被 npm 标记为坏版本的 4.18.04.18.x 已被维护者撤回且本包未使用_.template_.omit/_.unset仅以受控字面量 key 调用剩余两条 advisory 的暴露面不成立静态扫描修复0.12.9CodeQL 发现的js/incomplete-url-substring-sanitization与js/incomplete-sanitization。前者落在 org-id.ts 的 git remote 解析解析出 URL host 后用精确相等或子域后缀匹配host github.com || host.endsWith(.github.com)替换掉原先的includes()子串包含判断——这样既继续识别ssh.github.com/altssh.gitlab.com等官方替代 SSH 主机又能拒绝github.com.evil.com这类钓鱼式伪域名后者是删除 XML loader 中一行冗余的.replace(\n, )此前\s折叠已去除换行并顺带清理了该扫描项。此外0.12.13 将nextdevDependency 升级到 16.2.11一次性关闭四个 high 与五个 medium 公告含 middleware/proxy 绕过、Server Actions 与 rewrites 的 SSRF、Server Action DoS、Image Optimization SVG DoS0.12.10 把zod升到 4.4.3 以满足openrouter/ai-sdk-provider的zod^4.3.5peer 依赖此前钉在 4.1.12 会导致strict-peer-deps下npm install报ERESOLVE。变更日志也明确说明这些升级均为构建期依赖不改变运行时依赖与公共 API。七、弃用与迁移从lingo.dev/_compiler到lingo.dev/compiler自 0.10.1 起每次使用 legacy 编译器都会在控制台打印弃用警告见 _deprecation.ts同一进程只提示一次提示新一代编译器lingo.dev/compiler的五大特性先进的虚拟模块系统实现更好的代码分割内置开发期翻译服务器复数字检测与 ICU MessageFormat 支持改进的元数据管理缓存更优线程安全的并发构建支持。官方迁移指南packages/compiler/README.md给出了前后对照。Next.js 迁移// 迁移前legacy import lingoCompiler from lingo.dev/_compiler; import type { NextConfig } from next; const nextConfig: NextConfig {}; export default lingoCompiler.next({ sourceRoot: app, models: lingo.dev, })(nextConfig); // 迁移后new compiler import type { NextConfig } from next; import { withLingo } from lingo.dev/compiler/next; const nextConfig: NextConfig {}; export default async function (): PromiseNextConfig { return await withLingo(nextConfig, { sourceLocale: en, targetLocales: [es, fr], models: lingo.dev, }); }Vite 迁移// 迁移前legacy import { defineConfig, type UserConfig } from vite; import react from vitejs/plugin-react; import lingoCompiler from lingo.dev/_compiler; const viteConfig: UserConfig { plugins: [react()] }; export default defineConfig(() lingoCompiler.vite({ models: lingo.dev })(viteConfig) ); // 迁移后new compiler import { defineConfig, type UserConfig } from vite; import react from vitejs/plugin-react; import { withLingo } from lingo.dev/compiler/vite; const viteConfig: UserConfig { plugins: [react()] }; export default defineConfig(async () await withLingo(viteConfig, { sourceLocale: en, targetLocales: [es, fr], models: lingo.dev, }) );安装命令由npm install lingo.dev/_compiler变为npm install lingo.dev/compiler。新一代编译器在仓库中的实现位于 packages/new-compilerlegacy 版本的相关测试与工具则继续保留在 packages/compiler/src如 org-id.ts、llm-api-key.ts供对照学习。八、如何验证与进一步探索运行测试cd packages/compiler pnpm testvitest 配置见 vitest.config.ts关注 JSX 空白规范化 jsx-content-whitespace.spec.ts关注 Provider 元数据 provider-details.spec.ts关注 XML 往返序列化 xml2obj.spec.ts包依赖清单与版本钉死策略 package.json所有依赖均为精确版本无^/~。结语从packages/compiler/CHANGELOG.md的五十余条记录中可以看到一条清晰的演进曲线先是把LLM 翻译做成稳定的构建期管线0.1.x再扩展 Provider 生态与构建体系0.2.x–0.5.x随后用大量 patch 打磨 JSX 转换的边界行为0.6.x–0.9.x最后以统一 API 端点 三层依赖安全治理收官0.12.x并在 0.10.1 起明确将接力棒交给新一代lingo.dev/compiler。对于今天的使用者而言正确的姿态是理解 legacy 编译器的架构与配置语义以完成迁移评估然后直接采用新编译器以获得虚拟模块、开发翻译服务器、ICU 复数字支持与更安全的依赖基线。【免费下载链接】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),仅供参考
返回列表