@ansstory/hias 1.0.5 → 1.0.7

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 CHANGED
@@ -1,13 +1,549 @@
1
1
  # hias-cli
2
+
3
+ > 个人脚手架 CLI,内置国际化翻译工具链。
4
+
5
+ ## 安装
6
+
7
+ ```sh
8
+ npm i @ansstory/hias -g
9
+ ```
10
+
11
+ ## 使用
12
+
13
+ ```
14
+ hias <command> [options]
15
+ ```
16
+
17
+ ---
18
+
19
+ ## 快速开始(国际化翻译)
20
+
21
+ ### 1. 配置 API 密钥
22
+
23
+ 注册一个翻译服务商,然后在项目中生成配置文件:
24
+
25
+ ```sh
26
+ hias setting
27
+ ```
28
+
29
+ 编辑 `.hias/setting.json`,填入 `appId` 和 `secretKey`:
30
+
31
+ ```json
32
+ {
33
+ "translationSetting": {
34
+ "appId": "your_app_id",
35
+ "secretKey": "your_secret_key",
36
+ "provider": "baidu"
37
+ }
38
+ }
39
+ ```
40
+
41
+ > **没有 API 密钥?** 留空即可使用回退模式——中文原文直接作为 key,国际化迁移仍然可以完成。
42
+
43
+ ### 2. 预览变更(推荐)
44
+
45
+ ```sh
46
+ hias tfo src/views myNamespace --dry-run
47
+ ```
48
+
49
+ 显示行级 diff 并提示 `Apply changes? (y/N)`。
50
+
51
+ ### 3. 执行翻译
52
+
53
+ ```sh
54
+ hias tfo src/views myNamespace
55
+ ```
56
+
57
+ 语言包文件生成到 `.hias/lang/myNamespace/`。若 `replaceOriginalFile` 为 `true`,则直接覆盖源文件。
58
+
59
+ ---
60
+
61
+ ## 命令
62
+
63
+ ### `create <project>`(别名: `crt`)
64
+
65
+ 从框架模板创建项目。
66
+
67
+ 交互式提示列出所有可用框架。选择后模板将从 Gitee 下载到 `<project>/` 目录。
68
+
69
+ ```sh
70
+ hias create my-app
71
+ ```
72
+
73
+ **可用框架:**
74
+
75
+ | 名称 | 说明 |
76
+ | ------------ | ----------------------- |
77
+ | `vue2` | Vue 2 模板 |
78
+ | `vue3` | Vue 3 模板 |
79
+ | `vue-ts` | Vue 3 + TypeScript 模板 |
80
+ | `uni-vite` | uni-app + Vite 模板 |
81
+ | `nuxt-web` | Nuxt.js 网页模板 |
82
+ | `vue-screen` | Vue 数据大屏模板 |
83
+ | `react` | React JSX 模板 |
84
+ | `react-ts` | React TypeScript 模板 |
85
+
86
+ ---
87
+
88
+ ### `adv <name> [options]`
89
+
90
+ 添加 Vue 组件文件。
91
+
2
92
  ```sh
3
- npm i hias -g
4
- hias -h
5
- hias create xxx
6
93
  hias adv Demo -d src/components
94
+ hias adv index -d src/views/demo
95
+ ```
96
+
97
+ ### `adr <name> [options]`
98
+
99
+ 添加 React JSX 组件文件。
100
+
101
+ ```sh
7
102
  hias adr Demo -d src/components
103
+ ```
104
+
105
+ ### `adrt <name> [options]`
106
+
107
+ 添加 React TSX 组件文件。
108
+
109
+ ```sh
8
110
  hias adrt Demo -d src/components
111
+ ```
112
+
113
+ ### `adrd <name> [options]`
114
+
115
+ 添加 Redux JSX Store 文件。
116
+
117
+ ```sh
9
118
  hias adrd useDemoStore -d src/store/modules
119
+ ```
120
+
121
+ ### `adrdt <name> [options]`
122
+
123
+ 添加 Redux TSX Store 文件。
124
+
125
+ ```sh
10
126
  hias adrdt useDemoStore -d src/store/modules
127
+ ```
128
+
129
+ #### 组件命令通用选项
130
+
131
+ | 选项 | 说明 |
132
+ | ------------------- | ---------------------------------------------------------- |
133
+ | `-d, --dest <path>` | 目标文件夹,默认 `src/components`,支持 Windows 反斜杠路径 |
134
+
135
+ 如果 `name` 为 `index`,则组件文件以父文件夹名命名。
136
+
137
+ ---
138
+
139
+ ### `close-port <ports...>`
140
+
141
+ 关闭占用一个或多个端口的进程。
142
+
143
+ ```sh
11
144
  hias close-port 8076 8077
12
145
  hias close-port 8076,8077
146
+ hias close-port 3000
147
+ ```
148
+
149
+ 支持空格分隔和逗号分隔的端口列表。兼容 Windows(`netstat` + `taskkill`)、macOS 和 Linux(`lsof` + `kill`)。
150
+
151
+ ---
152
+
153
+ ### `lang [language]`
154
+
155
+ 设置或查看 CLI 语言。
156
+
157
+ ```sh
158
+ hias lang zh-CN
159
+ hias lang en
160
+ hias lang -l # 查看当前语言
161
+ ```
162
+
163
+ | 选项 | 说明 |
164
+ | ------------ | ------------ |
165
+ | `-l, --list` | 显示当前语言 |
166
+
167
+ 支持的语言:`en`、`zh-CN`。
168
+
169
+ 语言偏好存储在 `~/.hias-cli/config.json` 中。
170
+
171
+ ---
172
+
173
+ ### 翻译命令
174
+
175
+ 翻译系统从源文件中提取中文,替换为 `$t()` 国际化调用,并生成语言包 JSON 文件。支持百度翻译 API 和腾讯云 TMT API。
176
+
177
+ #### `tf [file] [name]`
178
+
179
+ 翻译单个文件。
180
+
181
+ ```sh
182
+ hias tf src/views/index.vue vue
183
+ hias tf src/views/index.vue vue --verbose
184
+ ```
185
+
186
+ | 参数 / 选项 | 说明 |
187
+ | -------------------- | --------------------------------------------------------------------- |
188
+ | `file`(位置参数) | 要翻译的文件路径 |
189
+ | `name`(位置参数) | 国际化命名空间 key(默认使用父目录名) |
190
+ | `-n, --name <name>` | 指定命名空间的另一种方式 |
191
+ | `--dry-run` | 预览变更但不实际修改文件(显示行级 diff,确认后执行) |
192
+ | `-v, --verbose` | 显示详细逐文件日志,替代进度 spinner |
193
+ | `--show-extractions` | 仅展示所有提取到的中文文本及其文件和位置,不执行翻译也不发送 API 请求 |
194
+
195
+ **支持的文件类型:** `.vue`、`.js`、`.ts`、`.jsx`、`.tsx`、`.json`
196
+
197
+ #### `tfo [folder] [name]`
198
+
199
+ 递归翻译文件夹内所有支持的文件。
200
+
201
+ ```sh
202
+ hias tfo src/views views
203
+ hias tfo src/views views --verbose
204
+ ```
205
+
206
+ | 参数 / 选项 | 说明 |
207
+ | --------------------- | --------------------------------------------------------------------------------------------------- |
208
+ | `folder`(位置参数) | 文件夹路径 |
209
+ | `name`(位置参数) | 国际化命名空间 key(默认使用文件夹名) |
210
+ | `-n, --name <name>` | 指定命名空间的另一种方式 |
211
+ | `--dry-run` | 预览变更但不实际修改文件(显示行级 diff,确认后执行) |
212
+ | `-v, --verbose` | 显示详细逐文件日志,替代进度 spinner |
213
+ | `--exclude <pattern>` | 排除匹配 glob 模式的文件(如 `**/*.test.js`、`node_modules/**`)。使用 minimatch 匹配。可多次指定。 |
214
+ | `--show-extractions` | 仅展示所有提取到的中文文本及其文件和位置,不执行翻译也不发送 API 请求 |
215
+
216
+ #### `setting`
217
+
218
+ 生成项目级翻译配置文件。
219
+
220
+ ```sh
221
+ hias setting
222
+ ```
223
+
224
+ 在当前项目目录下创建 `.hias/setting.json`。
225
+
226
+ #### `global-setting`
227
+
228
+ 生成全局翻译配置文件。
229
+
230
+ ```sh
231
+ hias global-setting
232
+ ```
233
+
234
+ 创建或更新 `~/.hias-cli/config.json`,保留已有的 `language` 设置。
235
+
236
+ #### `clear-config`
237
+
238
+ 删除全局配置目录 `~/.hias-cli`。
239
+
240
+ ```sh
241
+ hias clear-config
242
+ ```
243
+
244
+ 如果需要完全卸载 CLI 并清理用户配置,请执行:
245
+
246
+ ```sh
247
+ hias uninstall -g
248
+ ```
249
+
250
+ 该命令会先执行 `hias clear-config`,再执行 `npm uninstall @ansstory/hias -g`。npm v7+ 不会在卸载包时运行旧的 `preuninstall` / `postuninstall` 生命周期脚本,因此单独运行 `npm uninstall` 不会删除 home 目录下的配置文件。
251
+
252
+ #### `gitignore`
253
+
254
+ 将 `.hias` 添加到项目的 `.gitignore`。若文件不存在则创建,若已存在则追加条目。
255
+
256
+ ```sh
257
+ hias gitignore
258
+ ```
259
+
260
+ ---
261
+
262
+ #### `rollback`
263
+
264
+ 恢复上一次翻译操作的原文件并清理生成的输出。
265
+
266
+ 每次翻译运行会在 `.hias/.langbackup/<timestamp>_<name>/` 下创建一个快照。执行 `rollback` 会恢复最近一次快照并删除该快照,保留更早的快照供多次单步回滚。
267
+
268
+ ```sh
269
+ hias rollback
270
+ hias rollback --list # 列出所有可用备份
271
+ hias rollback --name 20250101_120000_vue # 回滚指定备份
272
+ hias rollback --keep 3 # 仅保留最近 3 个备份,删除更旧的
273
+ ```
274
+
275
+ **行为:** 若当时 `replaceOriginalFile` 为 `true`,则还原原始源文件;若为 `false`,则仅删除输出目录 `.hias/lang/<name>/`。
276
+
277
+ **`--keep` 行为:** 按备份目录名称(时间戳)排序,删除最旧的备份,只保留最近的 N 个。若备份总数 ≤ N 则不操作。
278
+
279
+ | 选项 | 说明 |
280
+ | ---------------- | ----------------------------------- |
281
+ | `-l, --list` | 列出所有可用备份 |
282
+ | `--name <name>` | 按名称回滚指定备份 |
283
+ | `--keep <count>` | 仅保留最近 N 个备份,删除更旧的备份 |
284
+
285
+ ---
286
+
287
+ ## 配置
288
+
289
+ ### 配置级联
290
+
291
+ 翻译设置按以下优先级解析:
292
+
293
+ 1. **项目级** — 当前工作目录下的 `.hias/setting.json`
294
+ 2. **全局** — `~/.hias-cli/config.json`(通过 `hias global-setting` 创建)
295
+ 3. **默认值** — 硬编码的默认值(如下所示)
296
+
297
+ ### 设置文件格式
298
+
299
+ ```json
300
+ {
301
+ "translationSetting": {
302
+ "locales": ["zh-CN", "en-US"],
303
+ "outDir": ".hias/lang",
304
+ "fallbackToKey": true,
305
+ "replaceOriginalFile": false,
306
+ "provider": "tencent",
307
+ "_provider_hint": "'baidu','tencent'",
308
+ "i18nCallTemplate": "$t",
309
+ "extensions": [".vue", ".js", ".ts", ".jsx", ".tsx", ".json"],
310
+ "appId": "",
311
+ "secretKey": ""
312
+ }
313
+ }
314
+ ```
315
+
316
+ ### 配置字段说明
317
+
318
+ | 字段 | 类型 | 默认值 | 说明 |
319
+ | --------------------- | ---------- | -------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
320
+ | `locales` | `string[]` | `["zh-CN", "en-US"]` | 语言代码列表。**第一个为源语言**,其余为目标语言。例如 `["zh-CN", "en-US", "ja-JP", "ko-KR"]` 会同时生成英文、日文、韩文三套语言包 |
321
+ | `outDir` | `string` | `".hias/lang"` | 生成的语言包和翻译副本的输出目录 |
322
+ | `fallbackToKey` | `boolean` | `true` | 翻译 API 不可用时是否生成 key |
323
+ | `replaceOriginalFile` | `boolean` | `false` | 为 `true` 时直接覆盖源文件(不复制到 `outDir`) |
324
+ | `provider` | `string` | `"tencent"` | 翻译服务商:`"baidu"` 或 `"tencent"` |
325
+ | `i18nCallTemplate` | `string` | `"$t"` | i18n 函数名。当包含 `{{key}}` 时直接替换;否则包装为 `$t('key')` |
326
+ | `extensions` | `string[]` | — | 覆盖支持的文件扩展名(如 `[".vue", ".ts"]`),默认支持所有类型 |
327
+ | `appId` | `string` | `""` | 百度 AppId 或腾讯 SecretId |
328
+ | `secretKey` | `string` | `""` | 百度 SecretKey 或腾讯 SecretKey |
329
+
330
+ ### 翻译服务商
331
+
332
+ | 服务商 | `provider` 值 | `appId` | `secretKey` |
333
+ | ---------- | ------------- | ------------- | -------------- |
334
+ | 百度翻译 | `"baidu"` | 百度 AppId | 百度 SecretKey |
335
+ | 腾讯云 TMT | `"tencent"` | 腾讯 SecretId | 腾讯 SecretKey |
336
+
337
+ `appId` 和 `secretKey` 都留空则使用回退模式(中文原文同时作为 key 和 value)。
338
+
339
+ > **配置校验:** 加载配置时会自动校验字段格式(如 `locales` 是否为数组、`provider` 是否为支持的枚举值、`appId`/`secretKey` 是否为字符串等)。格式不符合时将发出警告并回退至默认值,不会中断流程。
340
+
341
+ ### 翻译服务商配置
342
+
343
+ #### 百度翻译
344
+
345
+ 1. 访问 [百度翻译开放平台](https://fanyi-api.baidu.com/) 注册账号
346
+ 2. 创建应用获取 **AppId** 和 **SecretKey**
347
+ 3. 配置文件中设置 `"provider": "baidu"`
348
+
349
+ #### 腾讯云 TMT
350
+
351
+ 1. 访问 [腾讯云 TMT](https://console.cloud.tencent.com/tmt) 开通服务
352
+ 2. 创建 API 密钥获取 **SecretId**(填入 `appId`)和 **SecretKey**
353
+ 3. 配置文件中设置 `"provider": "tencent"`
354
+
355
+ ---
356
+
357
+ ## 输出结构
358
+
359
+ 翻译完成后会创建以下目录结构(假设 `locales: ["zh-CN", "en-US", "ja-JP"]`):
360
+
361
+ ```
362
+ .hias/
363
+ ├── setting.json # 项目级配置文件
364
+ ├── lang/
365
+ │ └── <命名空间>/
366
+ │ ├── zh-CN.json # 源语言包
367
+ │ ├── en-US.json # 目标语言包 ①
368
+ │ ├── ja-JP.json # 目标语言包 ②
369
+ │ └── <file>.vue # 翻译副本(仅 replaceOriginalFile=false 时)
370
+ ├── .translation-cache.json # 翻译缓存(自动生成)
371
+ └── .langbackup/
372
+ └── <时间戳>_<命名空间>/
373
+ └── <file>.vue.bak # 原始文件备份
374
+ ```
375
+
376
+ 语言包采用 `{ namespace: { key: value } }` 嵌套格式,可直接用于 `vue-i18n` 等库的模块注册。
377
+
378
+ ---
379
+
380
+ ## 翻译行为
381
+
382
+ ### 源码提取
383
+
384
+ 工具扫描源文件并从以下位置提取中文:
385
+
386
+ - **引号字符串**:`'中文'`、`"中文"`、`` `中文{expr}文` ``(模板字面量含表达式时拆分,仅提取静态中文段)
387
+ - **Vue 模板**:`{{ '中文' }}`、`<div>中文</div>`
388
+ - **Vue 复杂表达式**:`{{ isHidden || '中文' }}`、`{{ isHidden ?? '中文' }}`(提取表达式中的引号字符串)
389
+ - **Vue 指令**:`v-if="text1 == '中文'"`(提取指令表达式中的内联字符串)
390
+ - **JSX/TSX 文本节点**:`<span>中文 {name}</span>`(支持含表达式的混合文本)
391
+ - **JSX/TSX 属性**:`<div title="中文">` 或 `<div title={'中文'}>`
392
+ - **JSON 值**:`"key": "中文值"`
393
+ - **HTML 普通属性**:`<div title="兴趣">`(Vue 模板中)
394
+
395
+ 注释(`//`、`/* */`、`<!-- -->`)会被正确跳过。`data-*` 和 `aria-*` 属性会被排除。
396
+
397
+ ### 替换模式
398
+
399
+ | 上下文 | 替换前 | 替换后 |
400
+ | -------------------- | ------------------------- | -------------------------------------------------- |
401
+ | Vue 模板文本节点 | `<div>兴趣</div>` | `<div>{{ $t('demo.interest') }}</div>` |
402
+ | Vue 模板插值 | `{{ '兴趣' }}` | `{{ $t('demo.interest') }}` |
403
+ | Vue 复杂表达式 | <code>{{ isHidden &#124;&#124; '兴趣' }}</code> | <code>{{ isHidden &#124;&#124; $t('demo.interest') }}</code> |
404
+ | Vue 指令表达式 | `v-if="text1 == '文本'"` | `v-if="text1 == $t('demo.text')"` |
405
+ | Vue script / JS / TS | `'兴趣'` | `$t('demo.interest')` |
406
+ | JSX 文本节点 | `<div>兴趣</div>` | `<div>{$t('demo.interest')}</div>` |
407
+ | JSX 属性 | `<div title="兴趣">` | `<div title={$t('demo.interest')}>` |
408
+ | Vue v-bind 属性 | `<div :title="'兴趣'">` | `<div :title="$t('demo.interest')">` |
409
+ | 模板字面量 | `` `中文 ${name} 测试` `` | `` `$t('demo.chinese') ${name} $t('demo.test')` `` |
410
+ | JSON 值 | `"兴趣"` | `"interest"`(直接替换为翻译结果) |
411
+
412
+ ### 语言包文件格式
413
+
414
+ **翻译成功时**(基于英文的 key):
415
+
416
+ ```json
417
+ // zh-CN.json
418
+ { "demo": { "interest": "兴趣", "test": "测试" } }
419
+ // en-US.json
420
+ { "demo": { "interest": "interest", "test": "test" } }
421
+ // ja-JP.json(如果 locales 包含 ja-JP)
422
+ { "demo": { "interest": "興味", "test": "テスト" } }
423
+ ```
424
+
425
+ **翻译失败时**(根据中文自动生成简短 key):
426
+
427
+ ```json
428
+ // zh-CN.json 和 en-US.json
429
+ { "demo": { "提起妈妈的手_一股酸痛便涌上心头": "提起妈妈的手,一股酸痛便涌上心头...", "test": "测试" } }
430
+ ```
431
+
432
+ ### Key 生成规则
433
+
434
+ | 场景 | 来源 | Key 生成方式 | 最大长度 |
435
+ | ------------ | -------- | ------------------------ | -------- |
436
+ | API 翻译成功 | 英文译文 | 转 snake_case | 40 字符 |
437
+ | API 回退 | 原始中文 | 去标点、`。` → `_`,截断 | 40 字符 |
438
+
439
+ Key 会去重:若两段文本生成相同的截断 key,则自动追加 `_1`、`_2`……
440
+
441
+ ### 翻译 API 回退警告
442
+
443
+ 当翻译 API 调用失败(网络错误、凭据无效或频率限制)时,工具会在控制台输出警告,例如:
444
+
445
+ ```
446
+ ⚠ Translation API failed, falling back to Chinese keys for this batch
447
+ ```
448
+
449
+ 然后回退到基于中文的自动生成 key(参见上方 [Key 生成规则](#key-生成规则)),确保即使没有 API 连接也能继续进行国际化迁移。
450
+
451
+ > **逐文本回退:** 若批次内部分文本翻译成功、部分失败,仅失败文本走回退模式,成功文本仍使用英文 key。这避免了因单个文本翻译失败导致整批内容降级使用中文 key。
452
+
453
+ ### 翻译缓存
454
+
455
+ 每次成功的 API 翻译结果会缓存到 `.hias/.translation-cache.json`。下次翻译相同文本时(无论哪个命名空间),直接从缓存读取,避免重复的网络请求和 API 费用。
456
+
457
+ - 缓存以原文为键、目标语言为二级键:`{ "text": { "en": "translated" } }`
458
+ - 缓存文件破损或格式错误时自动忽略,不影响正常翻译流程
459
+ - 缓存自动在"空闲时"落盘(`setImmediate` 延迟写入),不阻塞翻译管线
460
+
461
+ ### 未使用翻译清理
462
+
463
+ 替换中文为 `$t()` 调用后,工具会检查现有的语言包 JSON 文件,**移除源文件中不再引用的 key**,防止语言包随时间积累过期条目。
464
+
465
+ 清理操作仅针对本次翻译操作使用的命名空间,且仅移除在所有扫描源文件中引用数为零的 key。
466
+
467
+ ### 命名空间规范化
468
+
469
+ 源文件中已有的 `$t('旧命名空间.key')` 调用会在翻译时自动更新为当前命名空间。
470
+
471
+ ### 预览模式(--dry-run)
472
+
473
+ 指定 `--dry-run` 时,工具会显示所有变更的行级 diff,但不实际修改文件。预览结束后提示 `Apply changes? (y/N)` — 输入 `y` 或 `yes` 执行变更,其他任何输入取消。
474
+
475
+ ### `i18nCallTemplate` 自定义
476
+
477
+ `i18nCallTemplate` 字段控制国际化函数名和调用格式:
478
+
479
+ | 模板值 | 生成结果 |
480
+ | ---------------------------- | ------------------------------------- |
481
+ | `"$t"`(默认) | `$t('demo.interest')` |
482
+ | `"$te"` | `$te('demo.interest')` |
483
+ | `"{{key}}"` | `demo.interest`(裸 key,无函数调用) |
484
+ | `"t('{{key}}')"` | `t('demo.interest')` |
485
+ | `"i18n.global.t('{{key}}')"` | `i18n.global.t('demo.interest')` |
486
+
487
+ 当模板 **包含** `{{key}}` 时,`{{key}}` 会被替换为 `namespace.subKey`;当 **不包含** `{{key}}` 时,包装为 `template('namespace.subKey')`。
488
+
489
+ ### 工作流建议
490
+
491
+ - **首次翻译前务必使用 `--dry-run`** 预览提取结果,确认无误后再执行
492
+ - **针对单文件翻译**:`hias tfo src/views/MyComponent myComp`
493
+ - **排除配置或生成文件**:`hias tfo src/views views --exclude "**/*.test.js" --exclude node_modules`
494
+ - **按模块划分命名空间**:例如 `src/views/user/` → 命名空间 `user`,`src/views/admin/` → 命名空间 `admin`,保持语言包小巧聚焦
495
+ - **启用 `replaceOriginalFile` 后及时回滚确认**:`hias rollback`
496
+ - **多次回滚**:每次 `rollback` 撤销一个快照,可多次执行逐步回退
497
+ - **重复翻译安全**:已有 `$t()` 调用会在重新提取前被剥离,重复运行只会添加剩余中文的翻译
498
+
499
+ ---
500
+
501
+ ## 全局配置
502
+
503
+ 全局配置文件位于 `~/.hias-cli/config.json`,语言设置和翻译设置共用此文件:
504
+
505
+ ```json
506
+ {
507
+ "language": "zh-CN",
508
+ "translationSetting": {
509
+ "locales": ["zh-CN", "en-US"],
510
+ "outDir": ".hias/lang",
511
+ "fallbackToKey": true,
512
+ "replaceOriginalFile": false,
513
+ "provider": "tencent",
514
+ "_provider_hint": "'baidu','tencent'",
515
+ "i18nCallTemplate": "$t",
516
+ "extensions": [".vue", ".js", ".ts", ".jsx", ".tsx", ".json"],
517
+ "appId": "",
518
+ "secretKey": ""
519
+ }
520
+ }
13
521
  ```
522
+
523
+ 由以下命令管理:
524
+
525
+ - **`hias lang <language>`** — 设置 `language`
526
+ - **`hias global-setting`** — 创建/更新 `translationSetting`
527
+ - **`hias clear-config`** — 删除 `~/.hias-cli`
528
+ - **`hias uninstall -g`** — 先执行 `hias clear-config`,再卸载全局包
529
+
530
+ ---
531
+
532
+ ## 全部命令一览
533
+
534
+ | 命令 | 别名 | 说明 |
535
+ | ----------------------- | ----- | ---------------------------- |
536
+ | `create <project>` | `crt` | 从框架模板创建项目 |
537
+ | `adv <name>` | – | 添加 Vue 组件 |
538
+ | `adr <name>` | – | 添加 React JSX 组件 |
539
+ | `adrt <name>` | – | 添加 React TSX 组件 |
540
+ | `adrd <name>` | – | 添加 Redux JSX Store |
541
+ | `adrdt <name>` | – | 添加 Redux TSX Store |
542
+ | `close-port <ports...>` | – | 关闭端口的进程 |
543
+ | `lang [language]` | – | 设置或查看 CLI 语言 |
544
+ | `tf [file] [name]` | – | 单个文件翻译 |
545
+ | `tfo [folder] [name]` | – | 递归翻译文件夹 |
546
+ | `setting` | – | 生成项目级翻译配置 |
547
+ | `global-setting` | – | 生成全局翻译配置 |
548
+ | `gitignore` | – | 添加 `.hias` 到 `.gitignore` |
549
+ | `rollback` | – | 回滚上一次翻译操作 |
@@ -12,6 +12,8 @@ const {
12
12
  } = require('./action')
13
13
  const { handleLanguageAction } = require('./lang')
14
14
  const { handleClosePortAction } = require('./close-port')
15
+ const { handleTranslateFileAction, handleTranslateFolderAction, handleSettingAction, handleGlobalSettingAction, handleRollbackAction, handleGitignoreAction } = require('./translate')
16
+ const { clearConfigDirectory, uninstallPackage } = require('../../scripts/cleanup-config')
15
17
 
16
18
  // 注册所有命令行指令
17
19
  const beginCommander = function (program) {
@@ -43,6 +45,75 @@ const beginCommander = function (program) {
43
45
 
44
46
  // 关闭端口命令
45
47
  program.command('close-port <ports...>').description(t('commands.closePort')).action(handleClosePortAction)
48
+
49
+ // 翻译文件命令:将单个文件中的中文替换为国际化调用并生成语言包
50
+ program
51
+ .command('tf [file] [name]')
52
+ .description(t('commands.translateFile'))
53
+ .option('-n, --name <name>', t('options.translateName'))
54
+ .option('--dry-run', 'preview changes without modifying files')
55
+ .option('--show-extractions', 'list all extracted Chinese texts without translating')
56
+ .option('-v, --verbose', 'verbose output with individual file logs')
57
+ .action((file, name, options) => {
58
+ name = name || options.name
59
+ options.name = name
60
+ if (!file) {
61
+ console.log(chalk.red(t('messages.translateFileRequired')))
62
+ return
63
+ }
64
+ handleTranslateFileAction(file, options)
65
+ })
66
+
67
+ // 翻译文件夹命令:递归翻译文件夹内所有支持的文件
68
+ program
69
+ .command('tfo [folder] [name]')
70
+ .description(t('commands.translateFolder'))
71
+ .option('-n, --name <name>', t('options.translateName'))
72
+ .option('--dry-run', 'preview changes without modifying files')
73
+ .option('--show-extractions', 'list all extracted Chinese texts without translating')
74
+ .option('--exclude <pattern>', 'exclude files matching glob pattern (e.g. **/*.test.js)', (val, acc) => acc.concat([val]), [])
75
+ .option('-v, --verbose', 'verbose output with individual file logs')
76
+ .action((folder, name, options) => {
77
+ name = name || options.name
78
+ options.name = name
79
+ if (!folder) {
80
+ console.log(chalk.red(t('messages.translateFolderRequired')))
81
+ return
82
+ }
83
+ handleTranslateFolderAction(folder, options)
84
+ })
85
+
86
+ // 生成翻译配置文件(项目级)
87
+ program.command('setting').description(t('commands.setting')).action(handleSettingAction)
88
+
89
+ // 生成全局翻译配置文件
90
+ program.command('global-setting').description(t('commands.globalSetting')).action(handleGlobalSettingAction)
91
+
92
+ // 清理全局配置目录
93
+ program.command('clear-config').description(t('commands.clearConfig')).action(() => clearConfigDirectory())
94
+
95
+ // 清理配置并卸载全局包
96
+ program.command('uninstall').option('-g, --global', 'uninstall global @ansstory/hias package').description(t('commands.uninstall')).action((options) => {
97
+ if (!options.global) {
98
+ console.log(chalk.yellow.bold('Usage: hias uninstall -g'))
99
+ return
100
+ }
101
+ uninstallPackage()
102
+ })
103
+
104
+ // 将 .hias 添加到 .gitignore
105
+ program.command('gitignore').description(t('commands.gitignore')).action(handleGitignoreAction)
106
+
107
+ // 回滚上一次翻译操作
108
+ program
109
+ .command('rollback')
110
+ .description(t('commands.rollback'))
111
+ .option('-l, --list', 'list available backups')
112
+ .option('--name <name>', 'specific backup name to rollback (default: latest)')
113
+ .option('--keep <count>', 'keep only N most recent backups, remove older ones')
114
+ .action((options) => {
115
+ handleRollbackAction(options)
116
+ })
46
117
  }
47
118
 
48
119
  module.exports = beginCommander