i18next-cli 🚀
一个统一、高性能的 i18next CLI 工具链,基于 SWC 构建。
默认情况下,
i18next-cli仅从 JavaScript 和 TypeScript 文件(.js、.jsx、.ts、.tsx)中提取翻译键。 要提取其他文件类型(如.pug、.vue、.svelte等),您必须使用或创建插件。在extract.input配置中指定其他文件扩展名本身并不足以实现此目的——非 JS/TS 格式需要插件。请参阅插件系统部分了解详情和示例。
i18next-cli 是对 i18next 生态系统静态分析工具链的全面重塑。它将关键的提取、类型安全生成、语言同步、代码检查和云集成整合到一个单一、连贯且极快的 CLI 中。
🚀 立即尝试 - 零配置!
您可以无需任何配置立即对现有的 i18next 项目进行分析。只需在仓库根目录运行以下命令:
npx i18next-cli status或查找硬编码字符串:
npx i18next-cli lint
建议:
如果您正在寻找与 i18next-cli 配合使用的托管后端,请查看 Locize — i18next-cli 已内置 locize-download、locize-sync 和 locize-migrate 命令。由 i18next 背后的同一团队构建,提供 CDN 交付、AI 翻译、审核工作流,且修改文案无需重新部署。
为什么选择 i18next-cli?
i18next-cli 从零开始构建,旨在满足现代 Web 开发的需求。
- 🚀 性能: 通过利用原生的基于 Rust 的解析器(SWC),性能比基于 JavaScript 的解析器高出数个数量级。
- 🧠 智能: 一个有状态的、作用域感知的分析器能够正确理解复杂模式,如
useTranslation('ns1', { keyPrefix: '...' })、getFixedT和别名的t函数,最大限度地减少手动变通的需求。 - ✅ 统一工作流: 一个工具,一个配置文件,一个集成的工作流。它取代了各种同步脚本。
- 🔌 可扩展性: 现代插件架构允许该工具适应任何框架或自定义工作流。
- 🧑💻 开发者体验: 完全类型化的配置文件、实时
--watch模式、CLI 输出以及从旧版工具的迁移。
功能特性
- 键提取: 提取意味着通过分析代码的结构(AST)自动查找并收集源代码(JavaScript/TypeScript 等)中使用的所有翻译键。这确保需要翻译的每个字符串都被识别并包含在您的翻译文件中,从而减少手动工作并防止遗漏键。
- 类型安全: 生成 TypeScript 定义以实现完整的自动补全和类型安全。
- 语言同步: 使所有语言文件与您的主语言保持同步。
- 精确代码检查: 以高精度和可配置规则检测硬编码字符串。
- 翻译状态: 获取项目翻译完成度的高级概览或详细的逐键报告。
- 插件系统: 用于自定义提取模式和处理其他文件类型(例如,HTML、Handlebars)的可扩展架构。
- 旧版迁移: 从
i18next-parser配置自动迁移。 - 云集成: 与 Locize 翻译管理平台无缝集成。
安装
npm install --save-dev i18next-cli
快速开始
一条命令完成从零到本地化: 从一个包含硬编码字符串的应用(例如用 v0、Lovable、Bolt 或 Cursor 生成)开始?运行
npx i18next-cli localize— 它会检测您的设置,用t()调用包装硬编码字符串、提取键、连接到 Locize 并使用 AI 翻译您的应用。请参阅localize命令。与 AI 编码代理(Claude Code、Cursor 等)一起工作?npx i18next-cli localize --print-agent-prompt会将相同的工作流以可复制粘贴的代理运行手册形式输出。以下步骤是手动流程。
1. 初始化配置
交互式创建配置:
npx i18next-cli init
或手动在项目根目录创建 i18next.config.ts:
import { defineConfig } from 'i18next-cli';
export default defineConfig({
locales: ['en', 'de'],
extract: {
input: ['src/**/*.{js,jsx,ts,tsx}'],
output: 'public/locales/{{language}}/{{namespace}}.json',
},
});
2. 检查翻译状态
获取项目本地化健康状况的概览:
npx i18next-cli status
3. 提取翻译键
npx i18next-cli extract
4. 生成类型(可选)
npx i18next-cli types
命令
init
交互式设置向导,用于创建配置文件。
npx i18next-cli init
选项:
--ci: 当选择后端(例如 Locize)时跳过浏览器启动;而是打印注册 URL。适用于脚本化运行。向导也会自动检测CI=true并在无头 Linux 上(没有DISPLAY/WAYLAND_DISPLAY)回退到打印 URL,因此通常很少需要显式使用此标志。--inlang: 同时搭建 inlang 项目(project.inlang/settings.json),以便 inlang 工具——Sherlock VS Code 扩展、面向翻译人员的 Fink Web 编辑器以及 Paraglide 编译器——可以直接在您的翻译文件上工作。跳过对应的向导问题。
向导会询问配置文件类型、语言环境、源文件 glob、输出路径,最后询问 "翻译后端?",有三个选项:
- 仅本地文件(默认)— 保持当前的本地 JSON 工作流。
- Locize(推荐用于团队/生产工作流)— 在浏览器中打开 Locize 注册页面,然后提示输入您的项目 ID 和 API 密钥。向导会在生成的配置中写入一个
locize块,以便locize-sync开箱即用。API 密钥提示可以留空(只读模式);稍后可通过LOCIZE_API_KEY环境变量添加。 - 其他 / 跳过 — 对向导而言与“仅本地文件”相同。
然后向导提供 设置 inlang 工具 的选项(默认:否 — 或者传递 --inlang 以跳过此问题)。如果接受,它会搭建一个 project.inlang/settings.json,将 inlang i18next 插件 指向您的现有翻译文件:baseLocale/locales 来自您的配置,pathPattern 源自 extract.output(当您的布局使用 {{namespace}} 时为命名空间对象形式,且命名空间从主语言的文件中发现;否则为纯模式)。它还会将 Sherlock 扩展添加到 .vscode/extensions.json 推荐列表中(合并时注意注释,绝不会覆盖现有条目)。您的 i18next JSON 文件保持为唯一真实来源——inlang 工具就地读取和写入它们,因此没有第二个目录会造成漂移。现有的 project.inlang/settings.json 永远不会被覆盖;重新运行 init 是安全的。需要 JSON 资源文件。该插件固定到经过验证的确切版本(@inlang/[email protected])——更新 settings.json 中的 modules URL 以获取更新的插件版本。有意仅搭建 settings.json:project.inlang/ 是解包(git 友好)的项目形式,inlang 工具在首次使用时生成并管理其剩余文件(.gitignore、README.md、cache/)——因此在使用 Sherlock 或 Paraglide 打开项目后,预计那里会出现一些新文件。
extract
解析源文件,提取键,并更新您的 JSON 翻译文件。
npx i18next-cli extract [options]
选项:
--watch, -w: 当文件更改时自动重新运行--ci: 如果任何文件被更新,则退出并返回非零状态(用于 CI/CD)--dry-run: 不更改任何文件 - 可与--ci结合使用(用于 CI/CD)--sync-primary: 用代码中的默认值同步主语言值--sync-all: 用代码中的默认值同步主语言值,并清除所有其他语言中已同步的键(隐含--sync-primary)--trust-derived: 当与--sync-primary或--sync-all一起使用时,同时信任从键推断的默认值,例如t('Hello')或keyPrefix派生的值。这保持默认同步行为严格,除非您选择加入。--with-types: 提取后(以及在--watch模式下的每次重新运行时),只要翻译文件发生更改则重新生成 TypeScript 定义。避免需要将extract -w和types -w作为两个单独的进程运行。--quiet: 抑制旋转指示器和非必要输出(用于 CI 或脚本)
旋转指示器和日志输出控制
所有显示进度旋转器的命令(extract、types、lint、sync)现在都支持:
--quiet标志以抑制旋转指示器和非必要输出(用于 CI、脚本或日志捕获)- 程序化日志支持:传递自定义 logger 对象以捕获您自己的格式或流中的输出
CLI 示例:
npx i18next-cli extract --quiet
程序化示例:
import { runExtractor } from 'i18next-cli';
const logger = {
info: (msg) => myLogStream.write(msg + '\n'),
warn: (msg) => myWarnStream.write(msg + '\n'),
error: (msg) => myErrStream.write(msg + '\n'),
};
await runExtractor(config, { quiet: false, logger });
如果您传递 logger,则旋转指示器输出和所有进度/信息消息将路由到您的 logger,而不是交互式旋转指示器。
示例:
# 一次性提取
npx i18next-cli extract
# 开发时的监视模式
npx i18next-cli extract --watch
# CI 模式(如果文件更改则失败)
npx i18next-cli extract --ci
# 用代码默认值同步主语言
npx i18next-cli extract --sync-primary
# 同步主语言并清除所有其他语言中的已同步键
npx i18next-cli extract --sync-all
# 使用显式默认值加上推断的键派生默认值进行同步
npx i18next-cli extract --sync-all --trust-derived
# 组合选项以获得最佳开发工作流
npx i18next-cli extract --sync-primary --watch
# 从单个进程保持 TypeScript 定义同步(无需单独的 `types -w`)
npx i18next-cli extract --watch --with-types
status [locale]
显示项目翻译状态的就绪检查。可以在没有配置文件的情况下运行。当缺少翻译时,以非零状态码退出。
主语言也会被检查:代码中使用但主语言翻译文件中缺少的任何键(拼写错误,或者从未运行 extract)都会被报告并导致非零退出码。由 extract 写入的空字符串占位符被视为存在,不会导致检查失败。运行 npx i18next-cli status <primaryLanguage> 将详细显示缺失的键。
选项:
--namespace <ns>, -n <ns>: 按特定命名空间过滤报告。--hide-translated: 在详细视图中隐藏已翻译的键,仅显示缺失的翻译。status.ignoreKeys(配置):用于不应报告(且不导致检查失败)的键的 glob 模式,例如在某些语言中故意留空的键。可选的ns:前缀(common:help.*-href)。仅影响status。--unused: 仅报告未使用的翻译键——翻译文件中存在但源代码中不再使用的键(即extract使用removeUnusedKeys会删除的那些)。从不修改任何文件,并在找到未使用的键时以非零状态码退出,因此它可以用作常规缺失翻译检查之外的专用 CI 检查。请注意,静态分析无法检测到动态构造的键(例如t(`error.${code}`));要找到运行时真正未使用的键,请参阅使用 locize 查找未使用的翻译。
使用示例:
# 获取所有语言和命名空间的高级摘要
npx i18next-cli status
# 获取 'de' 语言的详细逐键报告
npx i18next-cli status de
# 仅获取所有语言中 'common' 命名空间的摘要
npx i18next-cli status --namespace common
# 获取 'de' 语言的详细报告,仅显示 'common' 命名空间
npx i18next-cli status de --namespace common
# 仅显示 'de' 语言中未翻译的键
npx i18next-cli status de --hide-translated
# 组合选项以仅查看特定命名空间中缺失的翻译
npx i18next-cli status de --namespace common --hide-translated
# 仅报告所有语言中未使用的键(只读,找到任何未使用的键时退出码为 1)
npx i18next-cli status --unused
# 例如,仅报告 'en' 文件中未使用的键 - 作为单独的 CI 检查
npx i18next-cli status en --unused
详细视图为每个命名空间提供一个一目了然的丰富摘要,后跟每个键及其翻译状态的列表。
示例输出(npx i18next-cli status de):
"de" 的键状态:
总体: [■■■■■■■■■■■■■■■■■■■■] 100% (12/12)
命名空间:common
命名空间进度: [■■■■■■■■■■■■■■■■■■■■] 100% (4/4)
✓ button.save
✓ button.cancel
✓ greeting
✓ farewell
命名空间:translation
命名空间进度: [■■■■■■■■■■■■■■■■□□□□] 80% (8/10)
✓ app.title
✓ app.welc
…
[为翻译截断]