npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

babaofan-translate-cli

v1.0.4-beta.0

Published

Beta local CLI for scanning i18n calls, generating semantic keys, translating with Google AI Studio, and updating locale files.

Readme

babaofan-translate-cli

当前版本为 Beta 测试版。功能还在快速迭代,存在已知问题与兼容性风险,生产项目请先使用 --dry-run 验证,再决定是否正式改写源码。

Beta 安装方式:

npm install -D babaofan-translate-cli@beta

Beta 临时执行方式:

npx babaofan-translate-cli@beta create --languages zh-cn,en --files "src/**/*.vue,src/**/*.ts" --dry-run

GitHub 仓库地址:

https://github.com/2285907229/babaofan-translate-cli

一个本地运行的 i18n 翻译 CLI。

它的目标很直接:扫描前端项目中的 t("...")$t("...") 这类国际化调用,把中文词条提取出来,自动生成稳定的 i18n key,把源码里的中文调用改写成 key 调用,然后直接在本地通过 Google AI Studio 的 Gemini 模型完成翻译,最后生成对应的多语言文件。

整个过程在用户自己的终端闭环完成,不依赖自建后端服务。

功能概览

  • 扫描前端项目中的 i18n 调用
  • 支持 VuenvueuvueReactNext.jsNuxt 以及其他基于 JS/TS 的前端项目
  • 使用 AST 扫描,而不是简单正则
  • 直接调用 Google 官方 SDK @google/genai
  • 支持通过 config.js 配置默认 API Key
  • 支持命令行覆盖 API Key,例如 --apiKey=xxx
  • 支持指定扫描范围
  • 支持指定语言列表
  • 支持指定输出目录和输出格式
  • 支持自动把源码里的中文调用改写成 i18n key
  • 支持预览模式 --dry-run
  • 支持合并已有 locale 文件,而不是粗暴覆盖

工作原理

这个工具的执行流程分 4 步:

  1. 扫描项目文件
  2. 使用 AST 提取 t("中文")$t("中文")this.$t("中文") 等调用中的静态字符串
  3. 为每个词条生成稳定的 key
  4. 把源码里的 t("中文") 改成 t("生成的.key")
  5. 调用 Google Gemini 接口批量翻译
  6. 合并已有 locale 文件
  7. 生成或更新 locales/*.json 等翻译文件

为什么用 AST

正则方案看着省事,实际上很容易误伤:

  • 把普通字符串里的 t("xxx") 当成真实调用
  • 漏掉模板里的表达式
  • 遇到嵌套、换行、模板字符串时结果不稳定

AST 扫描会靠谱得多,至少不是拿锤子当手术刀。

支持的扫描文件类型

当前支持以下文件后缀:

  • .js
  • .jsx
  • .mjs
  • .cjs
  • .ts
  • .tsx
  • .mts
  • .cts
  • .vue
  • .nvue
  • .uvue
  • .uts

默认会忽略这些目录:

  • node_modules
  • dist
  • build
  • coverage
  • .next
  • .nuxt
  • .output
  • .turbo
  • .git
  • locales

这样做是为了避免把依赖、构建产物和已生成翻译文件再次扫进去。

安装依赖

项目已经依赖:

npm install

如果你是把这个 CLI 集成到别的项目里,确保目标环境至少满足:

  • 已安装 Node.js
  • 已安装当前项目依赖
  • 能访问 Google AI Studio / Gemini 接口

安装

建议作为开发依赖安装:

npm install -D babaofan-translate-cli

如果你想明确安装测试版,建议直接指定 beta tag:

npm install -D babaofan-translate-cli@beta

或者:

pnpm add -D babaofan-translate-cli

或者:

yarn add -D babaofan-translate-cli

方式 1:直接用 npx 执行

npx babaofan-translate create --languages zh-cn,en --files "src/**/*.vue,src/**/*.tsx" --dry-run

如果你想强制使用 Beta 版本测试:

npx babaofan-translate-cli@beta create --languages zh-cn,en --files "src/**/*.vue,src/**/*.tsx" --dry-run

方式 2:写进项目 scripts

在目标项目的 package.json 里加:

{
  "scripts": {
    "i18n:scan": "babaofan-translate create --languages zh-cn,en --files \"src/**/*.vue,src/**/*.tsx\" --dry-run",
    "i18n:run": "babaofan-translate create --languages zh-cn,en --files \"src/**/*.vue,src/**/*.tsx\""
  }
}

然后执行:

npm run i18n:scan
npm run i18n:run

方式 3:临时传入 API Key

npx babaofan-translate create --apiKey=你的_key --languages zh-cn,en --files "src/**/*.vue,src/**/*.tsx"

方式 4:通过环境变量

GEMINI_API_KEY=你的_key npx babaofan-translate create --languages zh-cn,en --files "src/**/*.vue,src/**/*.tsx"

Windows PowerShell 可以这样:

$env:GEMINI_API_KEY="你的_key"
npx babaofan-translate create --languages zh-cn,en --files "src/**/*.vue,src/**/*.tsx"

API Key 配置

默认 API Key 配置在 config.js

export const defaultGoogleApiKey = "你的_google_ai_studio_key";

你也可以不写死在配置里,而是在命令行传入:

node bin/i18n.js create --apiKey=你的_key

或者:

node bin/i18n.js create --api-key=你的_key

Key 优先级

当前优先级如下:

  1. 命令行传入的 --apiKey / --api-key
  2. config.js 中的 defaultGoogleApiKey
  3. 环境变量
    • GEMINI_API_KEY
    • GOOGLE_AI_STUDIO_API_KEY
    • GOOGLE_API_KEY

安全提醒

如果 config.js 里写了真实 Key,别傻乎乎直接提交到公开仓库。

更稳的方式是:

  • 本地开发时临时写 config.js
  • 或者使用环境变量
  • 或者在实际项目里用命令行参数覆盖

命令说明

1. 创建翻译文件

node bin/i18n.js create [options]

示例:

node bin/i18n.js create --languages zh-cn,en --files "src/**/*.{vue,js,jsx,ts,tsx}"

2. 为 uni_modules 模块生成翻译文件

node bin/i18n.js add uni_modules/模块名 [options]

示例:

node bin/i18n.js add uni_modules/demo --languages zh-cn,en

3. 清空翻译输出目录

node bin/i18n.js clear

npm script 用法

项目里已经定义了:

"scripts": {
  "i18n": "node bin/i18n.js"
}

所以也可以这样用:

npm run i18n -- create --languages zh-cn,en --files "src/**/*.{vue,js,jsx,ts,tsx}"

如果你要传 Key:

npm run i18n -- create --apiKey=你的_key --languages zh-cn,en --files "src/**/*.{vue,js,jsx,ts,tsx}"

注意这里中间那个 -- 不能少。

少了以后,参数不会传给脚本,命令看着像执行了,实际上啥也没喂进去,贼恶心。

参数说明

通用参数

--apiKey <key>

Google AI Studio API Key,适合 npm run xxx -- --apiKey=*** 这种场景。

--api-key <key>

--apiKey 作用一致,只是另一种写法。

--model <model>

指定 Gemini 模型。

默认值:

gemini-2.5-flash

--batch-size <size>

单批翻译条数。

默认值:

20

--files <paths>

指定扫描文件或 glob,多个值用英文逗号分隔。

示例:

--files "src/**/*.vue,src/**/*.tsx"

--languages <codes>

指定语言列表,多个值用英文逗号分隔。

示例:

--languages zh-cn,en,ja

如果不传,CLI 会尝试自动检测项目里的语言配置。

--output-dir <dir>

指定输出目录。

默认值:

locales

--output-format <format>

输出格式,可选:

  • auto
  • pair-array
  • object

说明:

  • auto:自动判断
  • pair-array:输出二维数组,例如 [[key, value]]
  • object:输出对象,例如 { "key": "value" }

--source-locale <code>

指定源语言代码,默认是:

zh-cn

--no-rewrite

只生成 locale 文件,不改写源码。

默认情况下,CLI 会自动把源码中的中文调用替换成生成后的 key。

--dry-run

预览模式。

开启后,CLI 会输出:

  • 开始翻译总览
  • 正在调用 Google AI 生成语义 key 的提示
  • 语义 key 分批生成进度提示
  • 哪些文件会被改写
  • 会生成哪些 key
  • 会写入哪些 locale 文件
  • 对应 locale 文件是新建还是合并已有文件

不会真正执行翻译、改写源码或写入文件。

注意:

  • 为了预览真正的语义 key,dry-run 仍可能调用 Google 来生成 key

输出格式说明

源码改写说明

默认情况下,工具会把源码里的调用:

t("你好")
$t("欢迎使用")
this.$t("按钮文案")

自动改成类似这样:

t("home.button.title")
$t("home.welcome.message")
this.$t("header.action.confirm")

同时在 locale 文件里生成:

{
  "home.button.title": "你好"
}

key 生成规则

当前 key 由三部分组成:

  1. 文件相对路径
  2. Gemini 生成的英文语义 key
  3. 必要时附加短 hash 做冲突兜底

补充说明:

  • 目录层级之间使用 .
  • 单个目录名内部会尽量保留原始语义,例如 tmp-generic-test 会保留为 tmp-generic-test
  • 不会把一个目录名再拆成 tmp.generic.test
  • 对明显的临时目录或测试目录,例如 tmp-*temp-*test-*playground,会自动压缩或忽略,避免 key 前缀过长
  • 对真正的业务模块目录,例如 user-centerorder-management,会尽量保留

这样做的目的是:

  • 保持 key 稳定
  • 尽量让 key 能被人看懂
  • 避免简单重名冲突
  • 不依赖外部服务来生成 key

如果你暂时不想改源码,可以显式传:

--no-rewrite

合并已有 locale 文件

默认情况下,工具写 locale 文件时会先读取已有文件,再把本次新生成的 key 合并进去。

也就是说:

  • 旧 key 会保留
  • 新 key 会追加
  • 同名 key 会用本次生成结果覆盖

支持两种已有文件格式:

  • object
  • pair-array

这意味着你项目里已经有一部分翻译内容时,不需要每次从零开始重建。

object

示例:

{
  "你好": "Hello",
  "欢迎使用": "Welcome"
}

pair-array

示例:

[
  ["你好", "Hello"],
  ["欢迎使用", "Welcome"]
]

自动检测语言配置

如果没有手动传 --languages,CLI 会尝试扫描这些路径里的语言配置:

  • plugins/locale.*
  • src/plugins/locale.*
  • src/i18n/**/*
  • i18n/**/*
  • config/**/*locale*
  • locales/**/*

它会尝试识别这些字段:

  • languages
  • locales
  • supportedLocales
  • availableLocales
  • supportedLngs

如果自动检测失败,请直接传:

--languages zh-cn,en

别跟 CLI 斗气,明确告诉它最省事。

本地测试

最小测试方式

先在你的项目里建一个测试文件,比如 src/test-i18n.ts

const a = t("你好");
const b = $t("欢迎使用");

然后执行:

node bin/i18n.js create --languages zh-cn,en --files "src/test-i18n.ts"

你应该看到什么

正常情况下,终端会看到类似输出:

开始翻译
● 项目 ...
● 提供方 Google AI Studio
● 模型 gemini-2.5-flash
● 词条 2 个

然后输出目录里会生成:

  • locales/zh-cn.json
  • locales/en.json

如果开启默认回写,还会看到源文件中的中文被替换成生成后的 key。

预览测试方式

如果你想先看结果,不想真正改文件,可以执行:

node bin/i18n.js create --languages zh-cn,en --files "src/test-i18n.ts" --dry-run

正常情况下,你会看到:

  • 改写文件数量
  • key 预览
  • locale 文件输出位置
  • 是新建还是合并已有文件

常见问题

1. 终端提示 词条 0 个

通常是下面几个原因:

  • --files 路径没写对
  • 文件里没有 t("静态字符串")$t("静态字符串")
  • 写的是 t(variable),这种动态参数当前不会提取

2. 终端提示 fetch failed

通常是:

  • API Key 无效
  • 当前网络访问不到 Google 接口
  • 本机网络环境限制了 Gemini 服务访问

这不是扫描逻辑的问题。

现在批量调用失败时,CLI 也会额外提示失败批次,例如:

语义命名失败:第 2/5 批(20 条)执行失败

这样可以更快判断是偶发网络问题,还是某一批词条太多、太杂。

3. npm run 参数不生效

检查是不是漏了这个:

npm run i18n -- create --languages zh-cn,en

中间那个 -- 必须有。

4. 为什么源码没有被替换

先看是不是传了:

--no-rewrite

如果传了这个参数,CLI 只生成 locale,不改源码。

另外,只有静态字符串调用才会被改写。

5. 为什么没有真正写文件

先看是不是传了:

--dry-run

如果传了,CLI 只预览,不会真正翻译、改源码或写 locale。

不过为了生成可预览的语义 key,它仍可能调用 Google。

6. 为什么有些调用没被提取

当前优先提取静态字符串调用,比如:

t("你好")
$t("欢迎使用")
this.$t("按钮文案")

像下面这种动态值,目前不会提取:

t(messageKey)
t(`prefix.${name}`)

这是故意的,不是 bug。

动态 key 一旦瞎提,生成结果十有八九一团糟。

推荐用法

Vue / Nuxt 项目

npm run i18n -- create --languages zh-cn,en --files "src/**/*.{vue,ts,js}"

React / Next 项目

npm run i18n -- create --languages zh-cn,en --files "src/**/*.{tsx,ts,jsx,js}"

指定输出目录

npm run i18n -- create --languages zh-cn,en --files "src/**/*.{vue,ts}" --output-dir src/locales

指定输出格式

npm run i18n -- create --languages zh-cn,en --files "src/**/*.{tsx,ts}" --output-format object

只生成 locale,不改源码

npm run i18n -- create --languages zh-cn,en --files "src/**/*.{vue,ts}" --no-rewrite

先预览,不真正执行

npm run i18n -- create --languages zh-cn,en --files "src/**/*.{vue,ts}" --dry-run

全项目递归扫描

node bin/i18n.js create --languages zh-cn,en --files "**/*.{vue,js,jsx,ts,tsx}" --dry-run

注意:

  • 不要写成 /*.{vue,js,jsx,ts,tsx},那只会扫项目根目录一层
  • 默认忽略目录仍然生效,所以不会去扫 node_modulesdistlocales 这些地方

未来可以继续扩展的方向

  • 自动合并已有 locale 文件
  • 支持更多 i18n 框架约定
  • 增加 --dry-run
  • 增加翻译缓存
  • 增加忽略规则

License

MIT