@agentscope-ai/i18n 0.1.3 → 0.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +193 -347
- package/lib/cli.js +51 -0
- package/package.json +1 -1
- package/skills/i18n-helper/SKILL.md +36 -14
package/README.md
CHANGED
|
@@ -1,44 +1,90 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @agentscope-ai/i18n
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
前端代码仓库中文国际化工具,支持 AI 智能翻译和多语言管理。
|
|
4
4
|
|
|
5
5
|
## 特性
|
|
6
6
|
|
|
7
|
-
-
|
|
8
|
-
-
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
- ↩️ 支持国际化代码还原为中文
|
|
19
|
-
- ⚙️ 可配置的文件匹配模式
|
|
20
|
-
- 🛠️ 简单易用的命令行工具
|
|
21
|
-
- 🚫 支持多种忽略功能(文件级别、行级别、块级别)
|
|
22
|
-
- 🎯 智能过滤标点符号和 emoji
|
|
7
|
+
- 自动检测并提取中文文本
|
|
8
|
+
- 支持 AI Agent 翻译和 MT 机器翻译两种模式
|
|
9
|
+
- 支持 JSX/TSX/TS/JS 文件解析
|
|
10
|
+
- 智能生成翻译 key(MT 模式下保留文件路径结构)
|
|
11
|
+
- 支持翻译 key 使用检查与自动清理
|
|
12
|
+
- 集成 Medusa 翻译平台(拉取翻译文件、生成 Excel)
|
|
13
|
+
- 支持增量更新,只翻译新增文案
|
|
14
|
+
- 支持国际化代码还原为中文
|
|
15
|
+
- 支持文件级、块级、行级忽略控制
|
|
16
|
+
- 自动过滤纯标点符号和 emoji
|
|
17
|
+
- 一键安装 IDE AI 助手的 i18n skill(Cursor / Qoder / Claude Code 等)
|
|
23
18
|
|
|
24
19
|
## 安装
|
|
25
20
|
|
|
26
21
|
```bash
|
|
27
|
-
|
|
28
|
-
|
|
22
|
+
npm install @agentscope-ai/i18n
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## 快速开始
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
# 1. 生成配置文件
|
|
29
|
+
npx i18n init-config
|
|
30
|
+
|
|
31
|
+
# 2. 修改 i18n.config.js 中的配置(targetPath、keyPrefix 等)
|
|
29
32
|
|
|
30
|
-
#
|
|
31
|
-
|
|
33
|
+
# 3. 在 .env 文件中填写 DASHSCOPE_APIKEY
|
|
34
|
+
|
|
35
|
+
# 4. 初始化翻译
|
|
36
|
+
npx i18n init
|
|
37
|
+
|
|
38
|
+
# 5. 后续新增文案时,增量翻译
|
|
39
|
+
npx i18n patch
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## 命令一览
|
|
43
|
+
|
|
44
|
+
| 命令 | 说明 |
|
|
45
|
+
|------|------|
|
|
46
|
+
| `npx i18n init-config` | 生成 `i18n.config.js` 配置文件 |
|
|
47
|
+
| `npx i18n init` | 初始化翻译(MT 模式,等同于 `init-mt`) |
|
|
48
|
+
| `npx i18n init-agent` | 初始化翻译(百炼 Agent 批量模式) |
|
|
49
|
+
| `npx i18n init-mt` | 初始化翻译(MT 机器翻译模式) |
|
|
50
|
+
| `npx i18n patch` | 增量翻译(MT 模式,等同于 `patch-mt`) |
|
|
51
|
+
| `npx i18n patch-agent` | 增量翻译(百炼 Agent 批量模式) |
|
|
52
|
+
| `npx i18n patch-mt` | 增量翻译(MT 机器翻译模式) |
|
|
53
|
+
| `npx i18n check` | 检查翻译 key 使用状态 |
|
|
54
|
+
| `npx i18n reverse` | 还原国际化代码为中文 |
|
|
55
|
+
| `npx i18n medusa` | 从 Medusa 平台拉取翻译文件 |
|
|
56
|
+
| `npx i18n install-skill` | 安装 IDE AI 助手的 i18n-helper skill |
|
|
57
|
+
|
|
58
|
+
### 通用选项
|
|
59
|
+
|
|
60
|
+
大部分命令支持以下通用选项:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
-c, --config <path> # 指定配置文件路径(默认查找 i18n.config.js)
|
|
64
|
+
-p, --target-path <path> # 覆盖配置中的 targetPath
|
|
65
|
+
--skip-confirm # 跳过所有确认提示
|
|
32
66
|
```
|
|
33
67
|
|
|
34
68
|
## 配置
|
|
35
69
|
|
|
36
|
-
|
|
70
|
+
### init-config — 生成配置文件
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
npx i18n init-config
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
将 `i18n.config.example.js` 模板复制到项目根目录作为 `i18n.config.js`,同时:
|
|
77
|
+
- 如果 `.env` 不存在,自动创建并写入 `DASHSCOPE_APIKEY=`
|
|
78
|
+
- 如果 `.gitignore` 中未包含 `.env`,自动追加
|
|
79
|
+
|
|
80
|
+
### 配置文件说明
|
|
37
81
|
|
|
38
82
|
```javascript
|
|
83
|
+
require('dotenv').config();
|
|
84
|
+
|
|
39
85
|
module.exports = {
|
|
40
86
|
// 不需要翻译的文件和路径列表
|
|
41
|
-
doNotTranslateFiles: ['node_modules', 'dist', '.git'
|
|
87
|
+
doNotTranslateFiles: ['node_modules', 'dist', '.git'],
|
|
42
88
|
|
|
43
89
|
// 要处理的文件类型
|
|
44
90
|
fileType: '.tsx,.ts,.js,.jsx',
|
|
@@ -47,7 +93,7 @@ module.exports = {
|
|
|
47
93
|
targetPath: './src',
|
|
48
94
|
|
|
49
95
|
// 翻译文件输出目录
|
|
50
|
-
localesFilePath: './src/locales',
|
|
96
|
+
localesFilePath: './src/i18n/locales',
|
|
51
97
|
|
|
52
98
|
// i18n实例文件输出目录
|
|
53
99
|
i18nFilePath: './src/i18n',
|
|
@@ -60,367 +106,219 @@ module.exports = {
|
|
|
60
106
|
|
|
61
107
|
// DashScope API配置
|
|
62
108
|
dashScope: {
|
|
63
|
-
//
|
|
64
|
-
keyTranslateAppId: '
|
|
109
|
+
// Agent 模式使用的工作流 appId
|
|
110
|
+
keyTranslateAppId: '',
|
|
65
111
|
|
|
66
|
-
//
|
|
112
|
+
// MT 模式使用的翻译工作流 appId(按语言配置)
|
|
67
113
|
valueTranslateAppId: {
|
|
68
|
-
'en-us': '
|
|
69
|
-
'ja-jp': '
|
|
70
|
-
// 可以添加更多语言
|
|
114
|
+
'en-us': '',
|
|
115
|
+
'ja-jp': '',
|
|
71
116
|
},
|
|
72
117
|
|
|
73
|
-
// API
|
|
74
|
-
apiKey:
|
|
118
|
+
// API密钥(从 .env 读取)
|
|
119
|
+
apiKey: process.env.DASHSCOPE_APIKEY,
|
|
75
120
|
|
|
76
|
-
//
|
|
77
|
-
batchSize: 50,
|
|
121
|
+
// Agent 批量翻译配置
|
|
122
|
+
batchSize: 50,
|
|
78
123
|
|
|
79
|
-
// MT
|
|
80
|
-
mtConcurrency:
|
|
81
|
-
mtDelay:
|
|
82
|
-
mtBatchSize:
|
|
124
|
+
// MT 翻译配置
|
|
125
|
+
mtConcurrency: 1, // 并发数
|
|
126
|
+
mtDelay: 1000, // 批次间延迟(ms)
|
|
127
|
+
mtBatchSize: 25, // 每批翻译条数
|
|
83
128
|
},
|
|
84
129
|
|
|
85
|
-
// Medusa
|
|
130
|
+
// Medusa 翻译平台配置(可选)
|
|
86
131
|
medusa: {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
// 标签名称(用于拉取文件)
|
|
91
|
-
tag: 'your-tag-name',
|
|
92
|
-
|
|
93
|
-
// 包类型(用于拉取文件)json/android/ios
|
|
132
|
+
appName: '',
|
|
133
|
+
appId: '',
|
|
134
|
+
tag: '',
|
|
94
135
|
type: 'json',
|
|
95
|
-
|
|
96
|
-
// 输出目录(用于拉取文件)
|
|
97
136
|
outputPath: './locales',
|
|
98
|
-
|
|
99
|
-
// 是否合并现有文件(用于拉取文件)
|
|
100
137
|
mergeExisting: true,
|
|
101
|
-
|
|
102
|
-
// 分组名称(用于生成 Excel 文件)
|
|
103
|
-
group: 'your-group-name',
|
|
104
|
-
|
|
105
|
-
// 语言映射配置(用于生成 Excel 文件)
|
|
138
|
+
group: '',
|
|
106
139
|
keyMap: {
|
|
107
|
-
'zh-cn': 'Simplified Chinese',
|
|
108
140
|
'en-us': 'English',
|
|
109
141
|
'ja-jp': 'Japanese',
|
|
110
|
-
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
};
|
|
114
|
-
```
|
|
115
|
-
|
|
116
|
-
## 忽略功能
|
|
117
|
-
|
|
118
|
-
工具提供了多种忽略功能,让你可以精确控制哪些内容需要翻译。
|
|
119
|
-
|
|
120
|
-
### 忽略功能优先级
|
|
121
|
-
|
|
122
|
-
1. **文件级别忽略** (`@i18n-ignore`) - 最高优先级,忽略整个文件
|
|
123
|
-
2. **块级别忽略** (`@i18n-ignore-block-start`/`@i18n-ignore-block-end`) - 忽略包裹的代码块
|
|
124
|
-
3. **行级别忽略** (`@i18n-ignore-line`) - 忽略特定行
|
|
125
|
-
|
|
126
|
-
### 1. 文件级别忽略
|
|
127
|
-
|
|
128
|
-
在文件的第一行添加注释来忽略整个文件:
|
|
129
|
-
|
|
130
|
-
```jsx
|
|
131
|
-
// @i18n-ignore
|
|
132
|
-
import React from 'react';
|
|
133
|
-
|
|
134
|
-
const Component = () => {
|
|
135
|
-
return <div>这个文件中的所有中文都不会被处理</div>;
|
|
136
|
-
};
|
|
137
|
-
```
|
|
138
|
-
|
|
139
|
-
或者:
|
|
140
|
-
|
|
141
|
-
```jsx
|
|
142
|
-
/* @i18n-ignore */
|
|
143
|
-
import React from 'react';
|
|
144
|
-
|
|
145
|
-
const Component = () => {
|
|
146
|
-
return <div>这个文件中的所有中文都不会被处理</div>;
|
|
142
|
+
'zh-cn': 'Simplified Chinese',
|
|
143
|
+
},
|
|
144
|
+
},
|
|
147
145
|
};
|
|
148
146
|
```
|
|
149
147
|
|
|
150
|
-
### 2. 行级别忽略
|
|
151
|
-
|
|
152
|
-
使用 `@i18n-ignore-line` 来忽略特定行:
|
|
153
|
-
|
|
154
|
-
```jsx
|
|
155
|
-
// JSX 注释形式
|
|
156
|
-
<p>这行文本不会被处理 {/* @i18n-ignore-line */}</p>
|
|
157
|
-
|
|
158
|
-
// 单行注释形式
|
|
159
|
-
<div>这行也不会被处理</div> // @i18n-ignore-line
|
|
160
|
-
|
|
161
|
-
// 变量声明
|
|
162
|
-
const message = '这个变量不会被处理'; // @i18n-ignore-line
|
|
163
|
-
```
|
|
164
|
-
|
|
165
|
-
### 3. 块级别忽略
|
|
166
|
-
|
|
167
|
-
使用 `@i18n-ignore-block-start` 和 `@i18n-ignore-block-end` 来忽略代码块:
|
|
168
|
-
|
|
169
|
-
```jsx
|
|
170
|
-
{/* @i18n-ignore-block-start */}
|
|
171
|
-
<div>这个块中的所有文本都不会被处理</div>
|
|
172
|
-
<span>这个也不会被处理</span>
|
|
173
|
-
<button>这个按钮文本也不会被处理</button>
|
|
174
|
-
{/* @i18n-ignore-block-end */}
|
|
175
|
-
|
|
176
|
-
// 或者使用单行注释形式
|
|
177
|
-
// @i18n-ignore-block-start
|
|
178
|
-
<div>这个块中的文本不会被处理</div>
|
|
179
|
-
<span>这个也不会被处理</span>
|
|
180
|
-
// @i18n-ignore-block-end
|
|
181
|
-
```
|
|
182
|
-
|
|
183
|
-
## 使用
|
|
184
|
-
|
|
185
|
-
### 命令行
|
|
186
|
-
|
|
187
|
-
```bash
|
|
188
|
-
# 批量翻译模式
|
|
189
|
-
npx i18n init # 初始化国际化(批量翻译)
|
|
190
|
-
npx i18n patch # 更新翻译(批量翻译)
|
|
191
|
-
|
|
192
|
-
# MT机器翻译模式(新增)
|
|
193
|
-
npx i18n init-mt # 初始化国际化(MT单条翻译)
|
|
194
|
-
npx i18n patch-mt # 更新翻译(MT单条翻译)
|
|
195
|
-
|
|
196
|
-
# 其他命令
|
|
197
|
-
npx i18n check # 检查翻译状态
|
|
198
|
-
npx i18n reverse # 还原国际化代码为中文
|
|
199
|
-
npx i18n medusa # 从 Medusa 平台拉取翻译文件
|
|
200
|
-
```
|
|
201
|
-
|
|
202
148
|
## 命令详解
|
|
203
149
|
|
|
204
|
-
### init -
|
|
150
|
+
### init / init-mt — 初始化翻译(MT 模式)
|
|
205
151
|
|
|
206
152
|
```bash
|
|
207
153
|
npx i18n init
|
|
208
154
|
```
|
|
209
155
|
|
|
210
|
-
|
|
211
|
-
1. 扫描指定目录中的文件
|
|
156
|
+
1. 扫描 `targetPath` 目录中的源文件
|
|
212
157
|
2. 提取中文文案
|
|
213
|
-
3.
|
|
214
|
-
4.
|
|
215
|
-
5.
|
|
158
|
+
3. 使用 MT 机器翻译逐条生成翻译 key(保留文件路径结构)
|
|
159
|
+
4. 翻译为配置的多语言
|
|
160
|
+
5. 替换代码中的中文为 `$i18n.get()` 调用
|
|
216
161
|
6. 询问是否生成 Medusa Excel 文件
|
|
217
162
|
|
|
218
|
-
### init-
|
|
163
|
+
### init-agent — 初始化翻译(Agent 批量模式)
|
|
219
164
|
|
|
220
165
|
```bash
|
|
221
|
-
npx i18n init-
|
|
166
|
+
npx i18n init-agent
|
|
222
167
|
```
|
|
223
168
|
|
|
224
|
-
|
|
225
|
-
1. 扫描指定目录中的文件
|
|
226
|
-
2. 提取中文文案
|
|
227
|
-
3. 使用MT机器翻译逐条生成翻译key(保留文件路径结构)
|
|
228
|
-
4. 使用MT机器翻译逐条翻译为配置的多语言
|
|
229
|
-
5. 支持并发控制,提高翻译效率
|
|
230
|
-
6. 替换代码中的中文为国际化函数调用
|
|
231
|
-
7. 询问是否生成 Medusa Excel 文件
|
|
169
|
+
使用百炼 Agent 工作流进行批量翻译,适合大量文案的初始化场景。
|
|
232
170
|
|
|
233
|
-
### patch -
|
|
171
|
+
### patch / patch-mt — 增量翻译(MT 模式)
|
|
234
172
|
|
|
235
173
|
```bash
|
|
236
174
|
npx i18n patch
|
|
237
175
|
```
|
|
238
176
|
|
|
239
|
-
|
|
240
|
-
1. 扫描新增的中文文案
|
|
241
|
-
2. 只翻译新增的内容(批量模式)
|
|
242
|
-
3. 更新现有的翻译文件
|
|
243
|
-
4. 询问是否生成 Medusa Excel 文件
|
|
177
|
+
只扫描和翻译新增的中文文案,更新现有翻译文件。
|
|
244
178
|
|
|
245
|
-
### patch-
|
|
179
|
+
### patch-agent — 增量翻译(Agent 批量模式)
|
|
246
180
|
|
|
247
181
|
```bash
|
|
248
|
-
npx i18n patch-
|
|
182
|
+
npx i18n patch-agent
|
|
249
183
|
```
|
|
250
184
|
|
|
251
|
-
|
|
252
|
-
1. 扫描新增的中文文案
|
|
253
|
-
2. 使用MT机器翻译逐条处理新增内容
|
|
254
|
-
3. 支持并发控制,提高更新效率
|
|
255
|
-
4. 更新现有的翻译文件
|
|
256
|
-
5. 询问是否生成 Medusa Excel 文件
|
|
185
|
+
使用百炼 Agent 工作流进行批量增量翻译。
|
|
257
186
|
|
|
258
|
-
### check
|
|
187
|
+
### check — 检查翻译状态
|
|
259
188
|
|
|
260
189
|
```bash
|
|
261
190
|
npx i18n check
|
|
191
|
+
npx i18n check --auto-delete-unused
|
|
262
192
|
```
|
|
263
193
|
|
|
264
|
-
这个命令会:
|
|
265
194
|
1. 检查代码中使用的翻译 key
|
|
266
195
|
2. 对比翻译文件的完整性
|
|
267
196
|
3. 显示缺失和未使用的 key
|
|
268
|
-
4.
|
|
197
|
+
4. `--auto-delete-unused`:自动删除未使用的 key
|
|
269
198
|
|
|
270
|
-
### reverse
|
|
199
|
+
### reverse — 还原国际化代码
|
|
271
200
|
|
|
272
201
|
```bash
|
|
273
202
|
npx i18n reverse
|
|
274
203
|
```
|
|
275
204
|
|
|
276
|
-
这个命令会:
|
|
277
205
|
1. 扫描文件中的 `$i18n.get` 调用
|
|
278
206
|
2. 提取 `dm`(default message)参数作为中文文本
|
|
279
|
-
3.
|
|
207
|
+
3. 替换为原始中文文本
|
|
280
208
|
4. 删除 `$i18n` 的导入语句
|
|
281
209
|
|
|
282
|
-
### medusa
|
|
210
|
+
### medusa — 从 Medusa 平台拉取翻译文件
|
|
283
211
|
|
|
284
212
|
```bash
|
|
285
|
-
npx i18n medusa
|
|
213
|
+
npx i18n medusa # 使用配置文件默认设置
|
|
214
|
+
npx i18n medusa --app my-app --tag main # 自定义应用和标签
|
|
215
|
+
npx i18n medusa --output ./src/locales # 自定义输出目录
|
|
216
|
+
npx i18n medusa --no-merge # 不合并,直接覆盖
|
|
286
217
|
```
|
|
287
218
|
|
|
288
|
-
|
|
289
|
-
1. 从 Medusa 平台拉取指定应用的翻译文件
|
|
290
|
-
2. 自动将语言标签转换为小写(如 en-US → en-us)
|
|
291
|
-
3. 支持合并现有文件或完全覆盖
|
|
292
|
-
4. 生成多语言 JSON 文件
|
|
219
|
+
支持的选项:
|
|
293
220
|
|
|
294
|
-
|
|
221
|
+
| 选项 | 说明 |
|
|
222
|
+
|------|------|
|
|
223
|
+
| `-c, --config <path>` | 配置文件路径 |
|
|
224
|
+
| `-o, --output <dir>` | 输出目录 |
|
|
225
|
+
| `-a, --app <name>` | Medusa 应用名称 |
|
|
226
|
+
| `-t, --tag <name>` | Medusa 标签名称 |
|
|
227
|
+
| `--type <type>` | 包类型(json/android/ios) |
|
|
228
|
+
| `--no-merge` | 不合并现有文件,直接覆盖 |
|
|
295
229
|
|
|
296
|
-
|
|
297
|
-
# 使用配置文件中的默认设置
|
|
298
|
-
npx i18n medusa
|
|
230
|
+
配置优先级:命令行参数 > 配置文件 > 默认值。
|
|
299
231
|
|
|
300
|
-
|
|
301
|
-
npx i18n medusa --config ./my-i18n.config.js
|
|
232
|
+
### install-skill — 安装 IDE i18n Skill
|
|
302
233
|
|
|
303
|
-
|
|
304
|
-
npx i18n
|
|
234
|
+
```bash
|
|
235
|
+
npx i18n install-skill
|
|
236
|
+
npx i18n install-skill --agent cursor qoder
|
|
237
|
+
npx i18n install-skill --app-id 12345
|
|
238
|
+
```
|
|
305
239
|
|
|
306
|
-
|
|
307
|
-
npx i18n medusa --app my-app --tag main
|
|
240
|
+
为 Cursor、Qoder、Claude Code、Codex、OpenCode 等 IDE 安装 i18n-helper skill。默认自动检测已有的 IDE 配置目录。
|
|
308
241
|
|
|
309
|
-
|
|
310
|
-
npx i18n medusa --type json
|
|
242
|
+
## 翻译模式对比
|
|
311
243
|
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
244
|
+
| | Agent 批量模式 (init-agent / patch-agent) | MT 机器翻译模式 (init / patch) |
|
|
245
|
+
|---|---|---|
|
|
246
|
+
| 翻译方式 | 批量翻译 | 逐条翻译 |
|
|
247
|
+
| 速度 | 快(批量处理) | 较慢(支持并发控制) |
|
|
248
|
+
| 翻译质量 | 一般 | 高(无上下文干扰) |
|
|
249
|
+
| Key 生成 | 批量生成 | 保留文件路径结构 |
|
|
250
|
+
| 错误隔离 | 批次粒度 | 单条粒度 |
|
|
251
|
+
| 适用场景 | 大量文案初始化 | 高质量翻译、增量更新 |
|
|
315
252
|
|
|
316
|
-
|
|
253
|
+
### 性能调优
|
|
317
254
|
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
255
|
+
```javascript
|
|
256
|
+
dashScope: {
|
|
257
|
+
// Agent 批量模式:调整每批数量,建议 50-200
|
|
258
|
+
batchSize: 50,
|
|
322
259
|
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
- `--no-merge`: 不合并现有文件,直接覆盖
|
|
260
|
+
// MT 模式:需满足 1000 / mtDelay * mtConcurrency <= API rps 限制
|
|
261
|
+
mtConcurrency: 1, // 并发数,建议 1-5
|
|
262
|
+
mtDelay: 1000, // 批次间延迟(ms)
|
|
263
|
+
mtBatchSize: 25, // 每次 API 调用翻译条数
|
|
264
|
+
}
|
|
265
|
+
```
|
|
330
266
|
|
|
331
|
-
##
|
|
267
|
+
## 忽略功能
|
|
332
268
|
|
|
333
|
-
|
|
269
|
+
工具支持三种级别的忽略控制,优先级从高到低:
|
|
334
270
|
|
|
335
|
-
###
|
|
271
|
+
### 1. 文件级别忽略
|
|
336
272
|
|
|
337
|
-
|
|
338
|
-
- 🚀 **速度快**:每批可配置数量(默认100条)一起翻译
|
|
339
|
-
- 💰 **成本低**:减少API调用次数
|
|
340
|
-
- 📦 **批量处理**:适合大量文案的初始化场景
|
|
341
|
-
- ⚙️ **可配置批次大小**:通过 `batchSize` 参数调整
|
|
273
|
+
在文件**第一行**添加注释,跳过整个文件:
|
|
342
274
|
|
|
343
|
-
|
|
344
|
-
-
|
|
345
|
-
|
|
346
|
-
- API调用成本敏感的项目
|
|
275
|
+
```jsx
|
|
276
|
+
// @i18n-ignore
|
|
277
|
+
import React from 'react';
|
|
347
278
|
|
|
348
|
-
|
|
279
|
+
const Component = () => {
|
|
280
|
+
return <div>这个文件中的所有中文都不会被处理</div>;
|
|
281
|
+
};
|
|
282
|
+
```
|
|
349
283
|
|
|
350
|
-
|
|
351
|
-
- 🎯 **精度高**:逐条翻译,避免批量翻译的上下文干扰
|
|
352
|
-
- 🔧 **智能Key生成**:保留文件路径结构(如:`app.components.Button.confirmDelete`)
|
|
353
|
-
- ⚡ **并发控制**:支持配置并发数,平衡速度与稳定性
|
|
354
|
-
- 🕒 **延迟控制**:支持配置请求间隔,避免API限流
|
|
355
|
-
- 📦 **批量调用**:每次API调用可翻译多条文案,应对速率限制
|
|
356
|
-
- 🛡️ **稳定性好**:独立翻译每条文案,错误不会相互影响
|
|
284
|
+
### 2. 块级别忽略
|
|
357
285
|
|
|
358
|
-
|
|
359
|
-
- 对翻译质量要求较高的项目
|
|
360
|
-
- 需要精确key命名的场景
|
|
361
|
-
- 增量更新,处理少量新增文案
|
|
286
|
+
使用 `@i18n-ignore-block-start` / `@i18n-ignore-block-end` 包裹代码块:
|
|
362
287
|
|
|
363
|
-
|
|
288
|
+
```jsx
|
|
289
|
+
{/* @i18n-ignore-block-start */}
|
|
290
|
+
<div>这个块中的所有文本都不会被处理</div>
|
|
291
|
+
<span>这个也不会被处理</span>
|
|
292
|
+
{/* @i18n-ignore-block-end */}
|
|
293
|
+
```
|
|
364
294
|
|
|
365
|
-
|
|
366
|
-
dashScope: {
|
|
367
|
-
// 批量翻译配置
|
|
368
|
-
batchSize: 50, // 每批处理50条,默认100
|
|
295
|
+
### 3. 行级别忽略
|
|
369
296
|
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
297
|
+
在行尾添加 `@i18n-ignore-line` 注释:
|
|
298
|
+
|
|
299
|
+
```jsx
|
|
300
|
+
<p>这行文本不会被处理 {/* @i18n-ignore-line */}</p>
|
|
301
|
+
const message = '这个变量不会被处理'; // @i18n-ignore-line
|
|
375
302
|
```
|
|
376
303
|
|
|
377
304
|
## 多语言支持
|
|
378
305
|
|
|
379
|
-
|
|
306
|
+
在 `valueTranslateAppId` 中配置各语言对应的工作流 appId:
|
|
380
307
|
|
|
381
308
|
```javascript
|
|
382
309
|
valueTranslateAppId: {
|
|
383
310
|
'en-us': 'english-app-id',
|
|
384
311
|
'ja-jp': 'japanese-app-id',
|
|
385
312
|
'ko-kr': 'korean-app-id',
|
|
386
|
-
// 更多语言...
|
|
387
313
|
}
|
|
388
314
|
```
|
|
389
315
|
|
|
390
|
-
|
|
391
|
-
- `zh-cn.json` - 中文(简体)
|
|
392
|
-
- `en-us.json` - 英文
|
|
393
|
-
- `ja-jp.json` - 日文
|
|
394
|
-
- 等等...
|
|
395
|
-
|
|
396
|
-
## Medusa 平台集成
|
|
397
|
-
|
|
398
|
-
工具提供了与 Medusa 平台的深度集成,支持两个主要功能:
|
|
399
|
-
|
|
400
|
-
### 1. 拉取翻译文件
|
|
401
|
-
|
|
402
|
-
使用 `npx i18n medusa` 命令可以直接从 Medusa 平台拉取翻译文件:
|
|
403
|
-
|
|
404
|
-
- **智能合并**: 默认情况下会合并现有文件,保留本地修改
|
|
405
|
-
- **语言标签标准化**: 自动将语言标签转换为小写(如 en-US → en-us)
|
|
406
|
-
- **多格式支持**: 支持 JSON、Android XML、iOS strings 等格式
|
|
407
|
-
- **灵活配置**: 支持命令行参数和配置文件
|
|
408
|
-
|
|
409
|
-
### 2. 生成 Excel 文件
|
|
410
|
-
|
|
411
|
-
当配置了 `medusa` 选项时,工具会在 init 和 patch 命令的最后询问是否生成 Excel 文件。
|
|
412
|
-
|
|
413
|
-
Excel 文件包含以下列:
|
|
414
|
-
- **AppName**: 配置文件中的 `medusa.appName`
|
|
415
|
-
- **Group**: 配置文件中的 `medusa.group`
|
|
416
|
-
- **Key**: 翻译的 key
|
|
417
|
-
- **其他列**: 根据 `medusa.keyMap` 配置,每列对应一种语言的翻译
|
|
418
|
-
|
|
419
|
-
文件命名格式:`medusa-translations-YYYY-MM-DD.xlsx`
|
|
316
|
+
每种语言会生成对应的翻译文件(`zh-cn.json`、`en-us.json`、`ja-jp.json` 等)。
|
|
420
317
|
|
|
421
318
|
## 代码示例
|
|
422
319
|
|
|
423
320
|
### 翻译前
|
|
321
|
+
|
|
424
322
|
```tsx
|
|
425
323
|
const Form = () => {
|
|
426
324
|
return (
|
|
@@ -434,6 +332,7 @@ const Form = () => {
|
|
|
434
332
|
```
|
|
435
333
|
|
|
436
334
|
### 翻译后
|
|
335
|
+
|
|
437
336
|
```tsx
|
|
438
337
|
import $i18n from '@/i18n';
|
|
439
338
|
|
|
@@ -449,6 +348,7 @@ const Form = () => {
|
|
|
449
348
|
```
|
|
450
349
|
|
|
451
350
|
### 还原后
|
|
351
|
+
|
|
452
352
|
```tsx
|
|
453
353
|
const Form = () => {
|
|
454
354
|
return (
|
|
@@ -461,85 +361,31 @@ const Form = () => {
|
|
|
461
361
|
};
|
|
462
362
|
```
|
|
463
363
|
|
|
464
|
-
##
|
|
465
|
-
|
|
466
|
-
工具会生成以下文件:
|
|
467
|
-
|
|
468
|
-
- `src/locales/zh-cn.json`: 中文翻译文件
|
|
469
|
-
- `src/locales/en-us.json`: 英文翻译文件
|
|
470
|
-
- `src/locales/ja-jp.json`: 日文翻译文件
|
|
471
|
-
- 等等...
|
|
472
|
-
|
|
473
|
-
## 环境变量
|
|
474
|
-
|
|
475
|
-
创建 `.env` 文件:
|
|
476
|
-
|
|
477
|
-
```env
|
|
478
|
-
# DashScope API 配置
|
|
479
|
-
DASH_SCOPE_API_KEY=your_api_key_here
|
|
480
|
-
DASH_SCOPE_MUST_KEY_TRANSLATE_APP_ID=your_key_translate_app_id
|
|
481
|
-
DASH_SCOPE_MUST_VALUE_TRANSLATE_APP_ID=your_value_translate_app_id
|
|
364
|
+
## 注意事项
|
|
482
365
|
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
366
|
+
1. 使用前请确保 `.env` 中已填写 `DASHSCOPE_APIKEY`
|
|
367
|
+
2. `reverse` 命令会永久删除国际化代码,请谨慎使用
|
|
368
|
+
3. 忽略标记必须出现在注释中,字符串中的标记不会被识别
|
|
369
|
+
4. Medusa 拉取功能需要确保网络连接到 Medusa 平台
|
|
370
|
+
5. MT 翻译的并发参数需满足 `1000 / mtDelay * mtConcurrency <= API rps 限制`
|
|
371
|
+
6. 错误日志自动记录到 `logs/` 目录下(`api-errors.log`、`translation-errors.log`、`mt-translation-errors.log`)
|
|
486
372
|
|
|
487
373
|
## 开发
|
|
488
374
|
|
|
489
375
|
```bash
|
|
490
376
|
# 安装依赖
|
|
491
|
-
|
|
377
|
+
pnpm install
|
|
492
378
|
|
|
493
379
|
# 运行测试
|
|
494
|
-
|
|
380
|
+
pnpm test
|
|
495
381
|
|
|
496
382
|
# 代码格式化
|
|
497
|
-
|
|
383
|
+
pnpm run format
|
|
498
384
|
|
|
499
385
|
# 代码检查
|
|
500
|
-
|
|
386
|
+
pnpm run lint
|
|
501
387
|
```
|
|
502
388
|
|
|
503
|
-
## 注意事项
|
|
504
|
-
|
|
505
|
-
1. 确保 DashScope API 配置正确
|
|
506
|
-
2. 翻译文件会保存在 `localesFilePath` 指定的目录中
|
|
507
|
-
3. i18n 实例文件会复制到 `i18nFilePath` 指定的目录中
|
|
508
|
-
4. Excel 文件会保存在翻译文件目录中
|
|
509
|
-
5. 工具会自动处理文件编码和格式问题
|
|
510
|
-
6. reverse 命令会永久删除国际化代码,请谨慎使用
|
|
511
|
-
7. **忽略功能**:
|
|
512
|
-
- 文件级别忽略优先级最高,会完全跳过文件处理
|
|
513
|
-
- 块级别忽略支持嵌套,会正确处理最近的 start 和 end 标记
|
|
514
|
-
- 行级别忽略在块级别忽略中仍然有效
|
|
515
|
-
- 所有忽略标记必须出现在注释中,字符串中的标记不会被误判
|
|
516
|
-
- 工具会自动过滤只包含标点符号或 emoji 的文本
|
|
517
|
-
8. **Medusa 拉取功能**:
|
|
518
|
-
- 需要确保网络连接到 Medusa 平台
|
|
519
|
-
- 默认合并现有文件,使用 `--no-merge` 可直接覆盖
|
|
520
|
-
- 语言标签会自动转换为小写格式
|
|
521
|
-
- 支持从配置文件读取默认设置,命令行参数优先级更高
|
|
522
|
-
9. **错误日志功能**:
|
|
523
|
-
- API 调用失败时会自动记录到 `logs/api-errors.log` 文件
|
|
524
|
-
- 翻译结果解析失败时会自动记录到 `logs/translation-errors.log` 文件
|
|
525
|
-
- MT翻译错误会记录到 `logs/mt-translation-errors.log` 文件
|
|
526
|
-
- 日志文件包含详细的错误信息、请求上下文和时间戳
|
|
527
|
-
- 日志目录会在首次错误时自动创建
|
|
528
|
-
10. **MT翻译功能**:
|
|
529
|
-
- MT翻译会替换原key的下标部分,保留文件路径结构
|
|
530
|
-
- 合理配置并发数,过高可能导致API限流,建议1-5之间
|
|
531
|
-
- 并发翻译支持错误隔离,单个翻译失败不影响其他翻译
|
|
532
|
-
- MT翻译适合对质量要求高的场景,批量翻译适合大规模处理
|
|
533
|
-
11. **性能调优建议**:
|
|
534
|
-
- 批量翻译:调整 `batchSize` 参数,建议50-200之间
|
|
535
|
-
- MT翻译:调整 `mtConcurrency`、`mtDelay` 和 `mtBatchSize` 参数平衡速度与稳定性
|
|
536
|
-
- 针对API速率限制:增加 `mtBatchSize` 减少调用次数,或增加 `mtDelay` 控制调用频率
|
|
537
|
-
- 网络不稳定时建议降低并发数和增加延迟时间
|
|
538
|
-
|
|
539
|
-
## 贡献
|
|
540
|
-
|
|
541
|
-
欢迎提交 Pull Request 或创建 Issue。
|
|
542
|
-
|
|
543
389
|
## 许可证
|
|
544
390
|
|
|
545
391
|
MIT
|
package/lib/cli.js
CHANGED
|
@@ -186,6 +186,57 @@ withCommonOptions(
|
|
|
186
186
|
}
|
|
187
187
|
});
|
|
188
188
|
|
|
189
|
+
program
|
|
190
|
+
.command('init-config')
|
|
191
|
+
.description('Create i18n.config.js configuration file from template')
|
|
192
|
+
.action(async () => {
|
|
193
|
+
try {
|
|
194
|
+
const cwd = process.cwd();
|
|
195
|
+
const configPath = path.resolve(cwd, 'i18n.config.js');
|
|
196
|
+
|
|
197
|
+
if (fs.existsSync(configPath)) {
|
|
198
|
+
console.error('❌ i18n.config.js 已存在,如需重新生成请先删除已有文件');
|
|
199
|
+
process.exit(1);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
const templatePath = path.join(__dirname, '../i18n.config.example.js');
|
|
203
|
+
if (!fs.existsSync(templatePath)) {
|
|
204
|
+
throw new Error(`模板文件未找到: ${templatePath}`);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
fs.copySync(templatePath, configPath);
|
|
208
|
+
|
|
209
|
+
// 检查 .env 文件是否存在
|
|
210
|
+
const envPath = path.resolve(cwd, '.env');
|
|
211
|
+
if (!fs.existsSync(envPath)) {
|
|
212
|
+
fs.writeFileSync(envPath, 'DASHSCOPE_APIKEY=\n', 'utf8');
|
|
213
|
+
console.log('📝 已创建 .env 文件,请填写 DASHSCOPE_APIKEY');
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// 检查 .gitignore 中是否包含 .env
|
|
217
|
+
const gitignorePath = path.resolve(cwd, '.gitignore');
|
|
218
|
+
if (fs.existsSync(gitignorePath)) {
|
|
219
|
+
const gitignoreContent = fs.readFileSync(gitignorePath, 'utf8');
|
|
220
|
+
if (!gitignoreContent.includes('.env')) {
|
|
221
|
+
fs.appendFileSync(gitignorePath, '\n.env\n', 'utf8');
|
|
222
|
+
console.log('📝 已将 .env 添加到 .gitignore');
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
console.log('');
|
|
227
|
+
console.log('✅ i18n.config.js 已创建!');
|
|
228
|
+
console.log(`📁 路径: ${configPath}`);
|
|
229
|
+
console.log('');
|
|
230
|
+
console.log('💡 后续步骤:');
|
|
231
|
+
console.log(' 1. 根据项目需要修改 i18n.config.js 中的配置');
|
|
232
|
+
console.log(' 2. 在 .env 文件中填写 DASHSCOPE_APIKEY');
|
|
233
|
+
console.log(' 3. 运行 npx i18n init 初始化翻译');
|
|
234
|
+
} catch (error) {
|
|
235
|
+
console.error('❌ 创建配置文件失败:', error.message);
|
|
236
|
+
process.exit(1);
|
|
237
|
+
}
|
|
238
|
+
});
|
|
239
|
+
|
|
189
240
|
program
|
|
190
241
|
.command('install-skill')
|
|
191
242
|
.description('Install i18n-helper skill for Cursor / Qoder / Claude Code and other IDEs')
|
package/package.json
CHANGED
|
@@ -105,29 +105,51 @@ description: 国际化(i18n)自动化助手。当用户要对项目目录执行i
|
|
|
105
105
|
|
|
106
106
|
使用 Chrome DevTools MCP 的 `new_page`(不要用 `navigate_page`,它会关闭当前页)打开上述 URL。
|
|
107
107
|
|
|
108
|
-
3.
|
|
108
|
+
3. **操作美杜莎页面(最小化交互次数)**
|
|
109
109
|
|
|
110
|
-
|
|
111
|
-
- `zh_CN` textarea
|
|
112
|
-
- `en_US` textarea(`value="当前英文值"`)
|
|
110
|
+
使用 `wait_for` 等待 `en_US` 或 `zh_CN` 文本出现(它会自动返回快照,无需再调 `take_snapshot`)。从快照中识别:
|
|
111
|
+
- `zh_CN` textarea、`en_US` textarea 的 uid
|
|
113
112
|
- 标签区域是否已有 `do_not_trans`
|
|
113
|
+
- 「保存」按钮 uid
|
|
114
114
|
|
|
115
|
-
|
|
115
|
+
**只修改用户指定的语言**,未指定的不要动。按以下顺序操作:
|
|
116
116
|
|
|
117
|
-
a. **填入文案** —
|
|
117
|
+
a. **填入文案** — 对每个需要修改的 textarea,通过 `evaluate_script` 设置值(可以在**一次调用**中同时处理多个 textarea):
|
|
118
118
|
```javascript
|
|
119
|
-
(
|
|
120
|
-
const
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
119
|
+
(zh, en) => {
|
|
120
|
+
const set = (el, v) => {
|
|
121
|
+
if (!el || v === null) return;
|
|
122
|
+
const setter = Object.getOwnPropertyDescriptor(window.HTMLTextAreaElement.prototype, 'value').set;
|
|
123
|
+
setter.call(el, v);
|
|
124
|
+
el.dispatchEvent(new Event('input', { bubbles: true }));
|
|
125
|
+
el.dispatchEvent(new Event('change', { bubbles: true }));
|
|
126
|
+
};
|
|
127
|
+
set(zh, '新中文值或null');
|
|
128
|
+
set(en, '新英文值或null');
|
|
129
|
+
return 'ok';
|
|
125
130
|
}
|
|
126
131
|
```
|
|
132
|
+
> 不需要修改的语言传 `null`,对应 `args` 中仍需传一个占位 uid(任意元素即可)。
|
|
127
133
|
|
|
128
|
-
b. **添加 do_not_trans
|
|
134
|
+
b. **添加 do_not_trans 标签**(如果快照中已有则**跳过此步**) — 通过 `evaluate_script` 一次完成:
|
|
135
|
+
```javascript
|
|
136
|
+
(combobox) => {
|
|
137
|
+
combobox.click();
|
|
138
|
+
return new Promise(resolve => {
|
|
139
|
+
setTimeout(() => {
|
|
140
|
+
const opt = [...document.querySelectorAll('[role="option"]')].find(el => el.textContent.trim() === 'do_not_trans');
|
|
141
|
+
if (opt) opt.click();
|
|
142
|
+
setTimeout(() => {
|
|
143
|
+
combobox.blur();
|
|
144
|
+
document.body.click();
|
|
145
|
+
resolve('done');
|
|
146
|
+
}, 200);
|
|
147
|
+
}, 300);
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
```
|
|
129
151
|
|
|
130
|
-
c. **保存并发布** —
|
|
152
|
+
c. **保存并发布** — 点击「保存」按钮(带 `includeSnapshot: true` 确认结果),然后截图展示当前状态,等待用户确认后再点击「立即发布」按钮。
|
|
131
153
|
|
|
132
154
|
## 注意事项
|
|
133
155
|
|