lm-i18n-scanner
v2.3.0
Published
CLI tool to scan translatable frontend text and generate i18n JSON files
Maintainers
Readme
lm-i18n-scanner
lm-i18n-scanner 是用于前端项目国际化迁移的命令行工具。它扫描 Vue、React 与 JS/TS 源码中的可翻译文案,生成 i18n key 和语言包;也可以将源码文本替换为 i18n 调用。
安装
npm install -D lm-i18n-scanner配置
工具读取 JSON 或 ESM JavaScript 配置。默认先读取执行命令目录下的 lm-i18n-scanner.config.json;仅当该文件不存在时,才读取 lm-i18n-scanner.config.js。通过 -c 或 --config 可指定其他位置。
{
"rootDir": "src",
"output": "locales/i18n-data.json",
"langs": ["zh-cn", "en", "ja"],
"defaultLocale": "zh-cn",
"include": ["**/*.{vue,tsx,ts,jsx,js}"],
"exclude": ["**/node_modules/**", "**/dist/**", "**/*.test.ts"],
"keyMappings": {
"确定": "confirm",
"取消": "cancel"
},
"templates": {
"vue": "$t('{key}')",
"jsx": "t('{key}', {params})"
}
}JavaScript 配置必须使用 ESM default 导出一个对象,字段与 JSON 配置相同:
export default {
rootDir: 'src',
output: 'locales/i18n-data.json',
langs: ['zh-cn', 'en', 'ja'],
defaultLocale: 'zh-cn',
include: ['**/*.{vue,tsx,ts,jsx,js}'],
exclude: ['**/node_modules/**', '**/dist/**', '**/*.test.ts'],
templates: {
vue: "$t('{key}')",
jsx: "t('{key}')"
}
}JavaScript 配置会作为受信任的本地代码执行。项目需要将 .js 文件视为 ESM,例如在 package.json 中设置 "type": "module"。
rootDir 缺省时使用配置文件所在目录。rootDir 和 output 的相对路径均以配置文件目录为基准;include 和 exclude 则以扫描根目录为基准。未配置的语言、文件匹配规则、排除规则与替换模板使用内置默认值。
扫描和语言包规则
DOM 选择器、事件名、classList token、存储 key/value 和结构属性赋值(如 element.id、button.type)会跳过;toast 等普通函数的文案、title 与 textContent 仍会扫描。
工具扫描所有包含自然语言文字的可替换文案,支持中文、英文、韩文等语言,不会根据字符集判断原文应写入哪个语言包。模板文本、脚本字符串、模板字符串,以及 title、placeholder、alt、label、aria-label、aria-description 属性值会参与扫描。模块路径、URL、相对或绝对资源路径、技术属性(例如 class、id、href、src、value、data-*)及已有的 t(...)、$t(...)、i18n.t(...) 调用会跳过。
defaultLocale 用于指定新文案的原文写入语言包,且必须包含在 langs 中;其他语言包为同一 key 创建空字符串。未配置 defaultLocale 时,原文写入 langs 的第一个语言。langs 不可为空。示例中 defaultLocale: 'en' 时,"Submit"、"提交" 和 "제출" 都写入 en 语言包。
中文文案保持使用拼音生成 key。英文等可规范化为 ASCII 的文案使用可读片段和稳定短 hash;韩文等其他文案使用 text_<hash>。需要固定 key 时,优先通过 keyMappings 显式指定。
文件内忽略指令
需要扫描文件但跳过个别文案或代码段时,可在源码中使用独占一行的忽略注释。JS、TS、JSX 和 TSX 使用 JS 注释:
// i18n-ignore-next-line
toast('Preview');
/* i18n-ignore-start */
const mockTitle = 'Preview title';
/* i18n-ignore-end */i18n-ignore-next-line 会忽略同一源码区域内下一个可扫描的文案节点,而不是简单跳过下一物理行。i18n-ignore-start 和 i18n-ignore-end 忽略两者之间的文案,且支持嵌套。
Vue 的 <template> 使用 HTML 注释,<script> 和 <script setup> 使用 JS 注释;template、script 和 script setup 之间不能跨区域配对:
<template>
<!-- i18n-ignore-next-line -->
<p>Preview</p>
</template>
<script setup>
// i18n-ignore-next-line
const preview = 'Preview';
</script>被忽略的文案不会参与扫描、语言包合并、key 生成或 apply 源码替换。指令必须独占一行;存在孤立的 i18n-ignore-end 或未关闭的 i18n-ignore-start 时,命令会停止并报出文件路径与行号。
插值文本
模板字符串中的插值会写入语言包消息。例如 `你好,${name}` 会生成 你好,{name},并在 apply 时替换为 t('key', { name })。简单标识符保留原参数名;复杂表达式会按出现顺序使用 param1、param2,例如 ${format(user.name)} 会传入 { param1: format(user.name) }。
替换模板可使用 {params} 占位符接收参数对象。若模板未包含 {params},工具会在插值调用的最后一个 ) 前自动追加参数对象;因此默认的 t('{key}') 会生成 t('key', { name })。
命令
scan
扫描可翻译文案并增量合并语言包,不修改源码。
lm-i18n-scanner scan
lm-i18n-scanner scan -c xxx/lm-i18n-scanner.config.json
lm-i18n-scanner scan -c xxx/lm-i18n-scanner.config.jsapply
重新扫描项目,更新语言包后将匹配的文案替换为配置的 i18n 调用。
lm-i18n-scanner apply
lm-i18n-scanner apply -c xxx/lm-i18n-scanner.config.json
lm-i18n-scanner apply -c xxx/lm-i18n-scanner.config.js生成的 key 使用相对文件路径和文案派生片段;已有语言包中的翻译与旧 key 不会被覆盖或删除。apply 只生成配置的调用表达式,不会自动添加 t 或 $t 的导入和初始化。本工具不提供 t 方法的实现;请结合 vue-i18n 等第三方国际化库使用,或按项目需要自行实现。
2.0 起只提供 lm-i18n-scanner 命令,旧的 i18n-scanner 命令已移除。
开发
npm install
npm run test
npm run buildLicense
ISC
