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

@tardis-ksh/intl-extract

v1.0.4

Published

CLI for extracting intl strings into Excel

Readme

intl-extract

用于扫描前端源码中的多语言调用,提取中文文案并导出为 intl.xlsx

当前实现基于 TypeScript + ESM,支持递归扫描 ts / tsx / js / jsx 文件,提取以下两类调用:

  • getIntl('key', '中文')
  • intl.get('key').d('中文')

同时支持一定容错能力,包括:

  • 多行格式化调用
  • 带对象参数的 intl.get(...)
  • 注释与双引号字符串
  • 嵌套的 intl.get(...).d(...)

功能特性

  • 递归扫描指定目录源码文件
  • 提取 getIntlintl.get().d() 文案
  • 将 key 拆分为“模板代码”和“代码”
  • 按配置语言输出行,默认 zh_CN,vi_VN,en_US
  • 未配置翻译接口且缓存未命中时,非 zh_CN 描述留空
  • 配置 OpenAI Responses API 兼容接口后可自动生成目标语言翻译,请求接口期间会在终端显示 loading 动画
  • 通过全局 ~/.intl-extract/.env--config 读取翻译配置
  • 通过全局 ~/.intl-extract/cache.db 按目标语言复用中文翻译缓存
  • 支持从已有 Excel 中导入完整中文到目标语言的翻译组到 cache.db
  • 将运行日志写入 ~/.intl-extract/logs/intl-extract.log 并自动轮转
  • 在重复判断前先合并完全相同的 key + 中文,并将同 key 不同中文的冲突项在 Excel 中高亮

安装

pnpm install

运行环境需使用支持 node:sqlite 的 Node.js 版本,否则翻译缓存会自动降级为不可用。

开发命令

运行测试:

pnpm test

本地运行 CLI:

pnpm dev -- --cwd . --out ./intl.xlsx

命令行用法

源码扫描模式:

pnpm dev -- --cwd <target-dir> --out <output-file>

Excel 补全模式:

pnpm dev -- --from-excel <input.xlsx> --out <output.xlsx>

Excel 导入缓存模式:

pnpm dev -- --import-excel-db <input.xlsx>

或构建后使用 npm bin:

pnpm build
node dist/cli.js --cwd <target-dir> --out <output-file>

参数

  • --cwd:要扫描的目录,默认当前工作目录;传入 --from-excel 时不会扫描源码
  • --out:输出 Excel 路径,默认 <cwd>/intl.xlsx
  • --ext:要扫描的扩展名列表,默认 ts,tsx,js,jsx
  • --formatter-codes:额外指定模板代码列表,使用英文逗号分隔;会和源码扫描、.env 配置一起合并去重
  • --languages:输出语言列表,使用英文逗号分隔,默认 zh_CN,vi_VN,en_US;若未包含 zh_CN 会自动补到首位
  • --from-excel:读取已有 Excel 并补齐配置语言中空白的非 zh_CN 描述;启用后不扫描源码
  • --import-excel-db:读取已有 Excel 中完整的中文到目标语言翻译组并写入 cache.db;启用后不扫描源码,也不会导出 Excel
  • --use-cache:是否读取并写入翻译缓存,默认 true;设为 false 时不读缓存也不写缓存
  • --config:自定义配置文件路径,默认 ~/.intl-extract/.env
  • --api-base:翻译接口地址
  • --api-key:翻译接口密钥
  • --model:翻译模型名

示例:

pnpm dev -- \
  --cwd ./src \
  --out ./dist/intl.xlsx \
  --ext ts,tsx \
  --languages zh_CN,vi_VN,en_US

Excel 补全模式

当已有 Excel 中存在空白目标语言描述时,可以使用 --from-excel 继续补齐:

pnpm dev -- --from-excel ./intl.xlsx --out ./intl-filled.xlsx

规则:

  • 启用 --from-excel 后不会扫描 --cwd 源码
  • 保留原 Excel 全部行和已有描述
  • 只补齐配置语言中非 zh_CN描述 为空的行
  • 通过相同 模板代码 + 代码zh_CN 行获取中文源文案
  • 找不到对应中文时,该目标语言行保持为空
  • 结果写入 --out

Excel 导入缓存模式

当已有 Excel 中已经包含完整的中文到目标语言对照时,可以将其直接写入全局缓存库:

pnpm dev -- --import-excel-db ./intl.xlsx

规则:

  • 启用 --import-excel-db 后不会扫描 --cwd 源码
  • 该模式走独立分支,--out 会被忽略,不会生成新的 Excel
  • 启动时仍会沿用现有初始化逻辑,自动准备 ~/.intl-extract/cache.db、日志目录等全局资源
  • 仅要求输入 Excel 文件存在且可读取
  • Excel 表头必须仍然是 模板代码 / 代码 / 语言 / 描述
  • 同一 模板代码 + 代码 视为一组,一行对应一种语言
  • 空白行、缺字段行、空语言行、空描述行会直接跳过,不参与导入
  • 缓存导入使用 zh_CN 作为源语言,配置语言中的其他语言作为目标语言
  • 若同一组内任一语言出现多条且描述不一致,视为用户填写错误,命令会直接失败且不写入 db
  • 同一组内重复行只要描述完全一致就允许导入
  • 只有同时存在可用 zh_CN 和目标语言描述的组才会写入 db;缺目标语言的组会被忽略
  • 若不同组里出现“同一中文在同一目标语言下对应多个不同翻译”,命令会直接失败且不写入 db
  • 写入 cache.db 时按 中文原文 + 目标语言 作为 key;若 db 中已存在相同组合,会用 Excel 中的描述覆盖更新

翻译配置

当同时提供以下 3 个参数时,会调用 OpenAI Responses API 兼容接口生成目标语言翻译:

  • --api-base
  • --api-key
  • --model

配置优先级如下:

  1. CLI 参数
  2. --config 指定文件
  3. 全局默认文件 ~/.intl-extract/.env
  4. 环境变量

支持的环境变量:

  • INTL_EXTRACT_API_BASE
  • INTL_EXTRACT_API_KEY
  • INTL_EXTRACT_MODEL
  • INTL_EXTRACT_FORMATTER_CODES
  • INTL_EXTRACT_LANGUAGES

默认配置文件示例:

INTL_EXTRACT_API_BASE=https://example.com/v1
INTL_EXTRACT_API_KEY=your-token
INTL_EXTRACT_MODEL=gpt-4o-mini
INTL_EXTRACT_FORMATTER_CODES=srm.common,srm.composition
INTL_EXTRACT_LANGUAGES=zh_CN,vi_VN,en_US

自定义配置文件示例:

pnpm dev -- \
  --cwd ./src \
  --out ./intl.xlsx \
  --config ./custom.env

如果未提供完整翻译配置:

  • 仍会生成 Excel
  • zh_CN 行正常输出
  • zh_CN 行在缓存未命中时会保留为空字符串

全局目录

工具会使用用户主目录下的全局目录:

~/.intl-extract/
├─ .env
├─ .env.example
├─ cache.db
└─ logs/
   ├─ intl-extract.log
   ├─ intl-extract.1.log
   └─ ...

说明:

  • CLI 启动时会自动创建 ~/.intl-extract/.env.examplecache.dblogs/
  • .env.example 为带默认模板注释的示例文件;如需默认翻译配置,请复制为 .env 后填写
  • cache.db 基于 node:sqlite中文原文 + 目标语言 为 key 缓存翻译,避免重复调用接口
  • logs/intl-extract.log 记录每次运行的配置摘要、扫描结果和缓存统计
  • 日志文件超过阈值后会自动轮转,保留最近 5 份

缓存控制:

  • 默认启用缓存,相同中文和目标语言组合会复用 ~/.intl-extract/cache.db 中的翻译
  • --use-cache=false 时不会读取缓存,也不会把 API 翻译结果写入缓存
  • 当没有 API 配置但缓存命中时,仍可使用缓存补齐目标语言
  • 当启用缓存且全部命中时,不会请求 API

输出说明

生成的 Excel 工作表名为 intl,列结构如下:

  • 模板代码
  • 代码
  • 语言
  • 描述

每个提取项会按 --languages / INTL_EXTRACT_LANGUAGES 输出对应语言行。默认输出三行:

  • 一行 zh_CN
  • 一行 vi_VN
  • 一行 en_US

key 拆分规则

  • 工具会先扫描当前目录源码中的 formatterCollections({ code: [...] })
  • 同时会合并 --formatter-codesINTL_EXTRACT_FORMATTER_CODES 中配置的额外 code
  • 若 key 命中一个或多个收集到的 code,则优先使用最长匹配的 code 作为 模板代码
  • 命中后,去掉此前缀后的剩余部分作为 代码
  • 若未命中任何 code,则继续使用原有回退规则:
    • hzero.common.*模板代码 = hzero.common
    • 其他 key 默认取前二段作为 模板代码

例如:

| 原始 key | 模板代码 | 代码 | | --- | --- | --- | | hzero.common.button.save | hzero.common | button.save | | hzero.document.upload.model.version | hzero.document.upload | model.version | | srm.composition.supplier.list.title | srm.composition | supplier.list.title |

终端输出

CLI 运行完成后会打印摘要:

当存在未缓存文案且翻译接口配置完整时,等待接口返回期间会显示 正在请求翻译接口... 的 spinner;接口返回或失败后会自动清理该 loading 行。

  • files:扫描文件数
  • items:提取到的文案条数
  • duplicates:重复 key 数量,仅统计“同一 key 对应多个不同中文”的冲突 key

重复判定规则

  • 在判断重复和输出 Excel 之前,会先按 key + 中文 完全匹配去重
  • 完全相同的 key + 中文 只保留其中一组,不会重复导出,也不会计入 duplicates
  • key 相同但中文不同,则视为重复
  • 这类重复项会继续保留,并在 Excel 中高亮,便于人工处理
  • cacheHits:命中缓存的条数
  • cacheMisses:未命中缓存的中文和目标语言组合数(即使翻译接口配置不完整、不会发起请求,也会计入缓存未命中)
  • groups:导入缓存模式下识别到的完整组数量
  • translated:成功翻译数量
  • translationFailures:翻译失败数量
  • imported:导入缓存模式下成功写入 db 的条数
  • output:输出文件路径

当前注意事项

  • 扫描器当前忽略 node_modules.git
  • 如果在仓库 root 运行,并且仓库里保留了 .worktrees,这些 worktree 下的源码也可能被一并扫描
  • 翻译返回值会校验占位符,若占位符不一致则该条目标语言翻译会被丢弃并计为失败
  • Responses 接口返回的翻译结果支持直接 JSON、```json 代码块,以及 output[*].content[*].text 形式的文本提取

构建与 npm 使用

构建:

pnpm build

构建产物输出到 dist/,npm bin 指向:

dist/cli.js

发布前脚本会执行:

pnpm test && pnpm build

本地构建后可直接运行:

node dist/cli.js --cwd ./src --out ./intl.xlsx
node dist/cli.js --from-excel ./intl.xlsx --out ./intl-filled.xlsx
node dist/cli.js --import-excel-db ./intl.xlsx

测试

项目使用 Vitest,当前覆盖内容包括:

  • CLI 参数解析
  • 配置优先级
  • 文件递归扫描
  • getIntl 提取
  • intl.get().d() 提取
  • 格式化/嵌套/注释场景提取
  • key 归一化
  • 目标语言翻译层
  • 翻译缓存降级
  • 日志写入与轮转
  • Excel 导出
  • Excel 导入缓存校验
  • CLI 最小端到端流程

运行:

pnpm test