ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

深入解析 @lit-labs/cli-localize:`lit localize` 命令的架构设计与本地化工作流

深入解析 @lit-labs/cli-localize:`lit localize` 命令的架构设计与本地化工作流 深入解析 lit-labs/cli-localizelit localize命令的架构设计与本地化工作流【免费下载链接】litLit is a simple library for building fast, lightweight web components.项目地址: https://gitcode.com/GitHub_Trending/li/litlit-labs/cli-localize是 Lit 本地化Localization工具链中的命令实现层负责为 Lit CLI 提供lit localize命令的能力。它本身不直接面向用户使用而是被lit-labs/cli动态加载并借助lit/localize-tools完成消息提取与本地化构建。阅读本文后你将掌握lit localize extract/lit localize build的完整使用流程、lit-localize.json配置文件的全部字段语义以及命令元数据与实现分离这一延迟加载设计背后的源码级原理。一、lit-labs/cli-localize在 Lit 本地化工具链中的定位Lit 的本地化能力由四个分层包共同构成理解它们的分工是掌握lit localize命令的前提包职责仓库路径lit/localize运行在浏览器中的运行时库提供msg()、str等 API 供模板调用packages/localize/README.mdlit/localize-tools提供lit-localize命令行工具及LitLocalizer核心实现负责消息提取、翻译校验与本地化构建packages/localize-tools/src/index.tslit-labs/cliLit 官方的统一命令行入口聚合help、localize、labs gen等命令packages/labs/cli/README.mdlit-labs/cli-localizelit localize命令的具体实现包向 Lit CLI 注册命令元数据并延迟加载执行逻辑packages/labs/cli-localize/README.md其中lit-labs/cli-localize的官方定位非常明确——Powers thelit localizecommand驱动lit localize命令。该包自身是内部实现细节官方文档明确建议不要直接使用它而是安装lit-labs/cli后从其中运行lit localize。二、安装与基本用法2.1 安装lit-labs/cli根据 packages/labs/cli/README.md 的说明CLI 有两种安装方式全局安装可在系统任意位置运行lit命令npm i -g lit-labs/cli项目内安装作为开发依赖确保与其他依赖的版本一致cd my-project npm i -D lit-labs/cli注意lit-labs/cli目前仅作为预发布pre-release版本提供用于早期测试可能存在缺陷、缺失功能与破坏性变更。生产项目使用前请评估风险。2.2 运行lit localize安装 CLI 后即可运行本地化子命令lit localize extract lit localize build当执行lit localize时CLI 会从最近的node_modules目录加载lit-labs/cli-localize包如果未找到会提议先安装它这正是 packages/labs/cli-localize/README.md 中描述的核心行为。因此在项目中安装lit-labs/cli的同时也应确保lit-labs/cli-localize及其依赖lit/localize-tools可用。直接运行不带子命令的lit localize会得到错误提示。从 src/index.ts 的实现可以看到此时命令会输出Use one of the localize subcommands, like lit localize build or lit localize extract. Run lit help localize for more help.并以退出码1结束。三、源码级架构命令元数据与实现分离的延迟加载设计lit-labs/cli-localize的源码结构非常精简仅两个 TypeScript 文件却体现了一个关键的设计思想将命令的元数据名称、描述、参数定义与命令的耗时实现分离并通过动态import()延迟加载实现。3.1 命令注册层src/index.tsgetCommand()是包对 Lit CLI 暴露的唯一接口返回一个localize命令定义包含两个子命令extract提取 lit-localize 消息build构建 lit-localize 项目。两个子命令都只声明了一个选项--config其默认值为./lit-localize.json即项目根目录下的本地化配置文件。这也说明lit localize的默认配置文件约定是lit-localize.json与lit/localize-tools的命令行工具保持一致。关键细节在于子命令的run实现async run({config}: {config: string}, console: Console) { const commands await import(./commands.js); await commands.extract(config, console); }这里使用await import(./commands.js)延迟加载实际的命令实现。文件顶部注释解释了原因见 src/commands.ts将命令的轻量元数据用于--help与参数解析与真实实现分离是因为加载实现会连带加载其全部依赖而如果加载所有命令实现的所有依赖会严重拖慢 CLI 的启动速度。这正是 CLI 工具常见的启动性能优化策略lit help、参数解析等只依赖元数据即可完成无需把lit/localize-tools、TypeScript 编译器这类重型依赖提前加载进内存。3.2 命令实现层src/commands.ts实现层直接复用了lit/localize-tools的核心类build命令的调用链const config readConfigFileAndWriteSchema(configPath); // 读取并校验配置 const localizer makeLocalizer(config); // 按 output.mode 实例化 const {errors} localizer.validateTranslations(); // 校验翻译占位符 if (errors.length 0) { throw new KnownError(...); } // 不一致则中止 await localizer.build(); // 执行构建extract命令的调用链const {messages, errors} localizer.extractSourceMessages(); if (errors.length 0) { printDiagnostics(errors); throw new KnownError(Error analyzing program); } console.log(Extracted ${messages.length} messages); await localizer.writeInterchangeFiles();makeLocalizer的工厂逻辑根据配置中output.mode的值分派实现类——transform模式 →TransformLitLocalizerruntime模式 →RuntimeLitLocalizer其他值 → 抛出 Internal error: unknown mode从源码结构看mode值实际上由 JSON Schema 的枚举约束为runtime或transform两种makeLocalizer的分支基本不会落到default。四、lit-localize.json配置文件全字段详解lit localize extract与lit localize build都读取--config指定的 JSON 配置文件默认./lit-localize.json。配置的读取、校验逻辑位于 packages/localize-tools/src/config.ts完整字段定义与 JSON Schema 见 packages/localize-tools/src/types/config.ts 和 packages/localize-tools/config.schema.json。4.1 顶层必填字段{ sourceLocale: en, targetLocales: [es-419, zh_CN], interchange: { ...: ... }, output: { ...: ... } }字段类型必填说明sourceLocalestring是源码中消息所使用的语言代码Locale。targetLocalesstring[]是消息将要被本地化到的语言代码数组。inputFilesstring[]条件必填要提取消息的文件名或 glob 模式数组除非指定了tsConfig否则必须提供若同时指定两者以inputFiles为准。tsConfigstring条件必填tsconfig.json 路径用于确定提取消息的源文件集合以及 transform 模式下构建所用的编译器选项若与inputFiles同时指定其文件集合会被inputFiles忽略。interchangeobject是本地化交换格式及其配置XLIFF 或 XLB。outputobject是输出模式及配置runtime或transform。patchesobject否针对特定 locale 消息的字符串替换补丁用于在不修改源文件、不重复完整本地化周期的情况下做小幅修正。从 localize-tools/src/index.ts 的实现可以确认inputFiles/tsConfig的实际处理若配置了tsConfig则先通过readTsConfig()读取编译器选项与文件集合再使用fastGlob.sync()按inputFiles以配置文件的baseDir为工作目录解析出绝对文件路径列表。4.2 交换格式interchangeXLIFF 与 XLBinterchange决定翻译文件的读写格式工具链支持两种XLIFFxliffinterchange: { format: xliff, xliffDir: data/localization }xliffDir必填读写.xlfXML 文件的目录每个目标语言对应文件路径xliffDir/locale.xlfplaceholderStyle可选默认x占位符的表示方式可选x使用x标签或ph使用ph标签不同本地化工具对占位符语法的支持程度不同可按需切换。XLBxlbinterchange: { format: xlb, outputFile: data/localization/en.xlb, translationsGlob: data/localization/*.xlb }outputFile必填提取出的全部消息写入的 XLB XML 文件路径translationsGlob必填包含已翻译消息的 XLB 文件的 glob 模式语法遵循 node-glob 规范。4.3 输出模式outputruntime 与 transformoutput.mode决定本地化构建的产物形态这是lit localize build的核心分叉点。runtime 模式——为每个目标语言生成独立的翻译模块运行期动态选择语言output: { mode: runtime, outputDir: locales, language: ts, localeCodesModule: src/locales.ts }字段说明定义见 packages/localize-tools/src/types/modes.tsoutputDir必填生成模块的输出目录每个targetLocale会生成一个locale.ts或.js模块导出按消息 ID 索引的翻译language可选生成模块的语言js或ts默认规则为——若配置了tsConfig则默认ts否则默认jslocaleCodesModule可选生成一个导出sourceLocale、targetLocales、allLocales的模块用于保持配置文件与客户端配置同步路径需以.js或.ts结尾以决定生成的语言。transform 模式——为每个目标语言生成一份完整的项目副本构建期即完成替换output: { mode: transform, outputDir: localized }字段说明见 packages/localize-tools/src/types/modes.tsoutputDir可选转换后项目的输出目录每个语言在该目录下生成一个子目录内含该语言完整的项目构建未指定时默认使用tsConfig中的outDir两者都指定时以outputDir为准。4.4 补丁patches不重跑本地化周期的微调手段patches允许对特定语言、特定消息做字符串替换典型用法是修正翻译中的拼写错误而不必修改源文件或等待新一轮翻译。Schema 中的示例见 packages/localize-tools/config.schema.jsonpatches: { es-419: { greeting: [ { before: Buenos dias, after: Buenos días } ] } }每条补丁由before要搜索的字符串与after替换结果组成类型定义见 packages/localize-tools/src/types/config.ts。在 runtime 模式的生成逻辑中补丁通过applyPatches()在写入翻译模块前应用见 packages/localize-tools/src/modes/runtime.ts。4.5 自动写入$schema一个实用细节readConfigFileAndWriteSchema()在读取配置后如果 JSON 中缺少$schema属性会自动补写并回写文件见 packages/localize-tools/src/config.ts。这使得 VSCode 等编辑器能够基于config.schema.json提供配置校验与自动补全。这是lit localize命令首次运行时顺带发生的副作用值得留意。五、底层构建原理LitLocalizer与两种输出模式的实现5.1 共享的核心流程无论哪种模式build与extract都建立在LitLocalizer抽象基类之上见 packages/localize-tools/src/index.ts核心方法包括extractSourceMessages()通过ts.createProgram()构建 TypeScript 程序静态分析源码中所有msg调用并提取消息结果会被缓存readTranslationsSync()通过格式化器makeFormatter将翻译文件如 XLIFF读入MapLocale, Message[]以 locale 为键validateTranslations()调用validateLocalizedPlaceholders()校验每条翻译的 HTML 标签与模板表达式占位符是否与源消息完全一致writeInterchangeFiles()将提取的消息按名称排序后写回交换格式文件XLIFF/XLB。build命令在validateTranslations()返回错误时会直接中止错误信息见 src/commands.tsOne or more localized templates contain a set of placeholders (HTML or template literal expressions) that do not exactly match the source code, aborting.这意味着翻译文件中的占位符集合HTML 标签、${}表达式必须与源消息严格一致否则本地化构建会被拒绝执行。5.2 runtime 模式的产物生成packages/localize-tools/src/modes/runtime.ts 中的runtimeOutput()展示了 runtime 构建的完整细节若配置了localeCodesModule先写入 locale 代码模块创建outputDir无写权限时报 Error creating locales directory对每个targetLocale合并翻译与规范消息应用补丁生成export const templates { ... }形式的模块写入outputDir/locale.ext。生成模块的头部会注明Do not modify this file by hand! Re-generate this file by running lit-localize明确告知开发者该文件是构建产物。此外生成逻辑对每个 locale 有两种兜底行为见 runtime.ts翻译文件中存在、但规范消息中不存在的消息跳过并输出警告规范消息存在、但该 locale 缺少翻译使用源语言文本作为回退并输出警告。这保证了构建在翻译不完整时仍能产出可用的模块。5.3 运行时 API 与 CLI 的配合lit/labs/cli-localize服务于构建期/提取期工作流而浏览器运行期由lit/localize承担。在源码中使用方式见 packages/localize/README.mdimport {msg} from lit/localize; import {html} from lit; render() { return msg(htmlHello bWorld/b); }典型完整工作流如下编写源码用msg()包裹需要翻译的模板配置lit-localize.json含sourceLocale、targetLocales、interchange、output运行lit localize extract生成 XLIFF/XLB 交换文件交由翻译人员或翻译服务处理翻译完成后运行lit localize build校验占位符并产出本地化构建runtime 模式的 locale 模块或 transform 模式的分语言项目副本。六、注意事项与局限不要直接依赖lit-labs/cli-localize其 APIgetCommand面向 Lit CLI 内部注册机制设计属于实现细节官方文档明确建议经由lit-labs/cli使用预发布状态lit-labs/cli整体处于 pre-release 阶段lit-labs/cli-localize当前仓库中版本为 0.2.2见 package.json可能存在破坏性变更环境要求lit-labs/cli-localize的engines声明要求 Node.js14.8.0占位符一致性校验翻译中一旦出现与源消息不一致的 HTML 标签或表达式占位符build会整体中止建议在翻译工作流中加入校验环节。七、进一步探索如需深入源码建议按以下顺序阅读packages/labs/cli-localize/src/index.ts —— 命令注册与延迟加载入口packages/labs/cli-localize/src/commands.ts —— 两个子命令的实现与错误处理packages/localize-tools/src/config.ts —— 配置读取、校验与$schema自动写入packages/localize-tools/config.schema.json —— 配置的权威 JSON Schema 定义packages/localize-tools/src/index.ts ——LitLocalizer抽象基类与提取/校验/写入流程packages/localize-tools/src/modes/runtime.ts —— runtime 输出模式的模块生成细节packages/localize/README.md —— 浏览器运行期msg()API 的使用示例packages/labs/cli/README.md —— CLI 安装与lit localize命令的总览。【免费下载链接】litLit is a simple library for building fast, lightweight web components.项目地址: https://gitcode.com/GitHub_Trending/li/lit创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表