@ansstory/hias 1.0.6 → 1.0.8
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.en-US.md +551 -0
- package/README.md +245 -229
- package/lib/core/commander.js +14 -1
- package/lib/i18n/resources/en.json +2 -0
- package/lib/i18n/resources/zh-CN.json +2 -0
- package/package.json +1 -1
- package/scripts/cleanup-config.js +82 -0
- package/test/cleanup-config.test.js +73 -0
- package/test/commands.test.js +14 -0
- package/README.zh-CN.md +0 -531
package/README.en-US.md
ADDED
|
@@ -0,0 +1,551 @@
|
|
|
1
|
+
# hias-cli
|
|
2
|
+
|
|
3
|
+
> Personal scaffolding CLI with built-in i18n translation toolkit.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
npm i @ansstory/hias -g
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
hias <command> [options]
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Quick Start (i18n Translation)
|
|
20
|
+
|
|
21
|
+
### 1. Set up API credentials
|
|
22
|
+
|
|
23
|
+
Register a translation provider and create a config file in your project:
|
|
24
|
+
|
|
25
|
+
```sh
|
|
26
|
+
hias setting
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Edit `.hias/setting.json` with your `appId` and `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
|
+
> **No API key?** Leave both empty for fallback mode — Chinese text is used as keys directly. The i18n migration still completes.
|
|
42
|
+
|
|
43
|
+
### 2. Preview changes (recommended)
|
|
44
|
+
|
|
45
|
+
```sh
|
|
46
|
+
hias tfo src/views myNamespace --dry-run
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Shows a line-level diff and prompts `Apply changes? (y/N)`.
|
|
50
|
+
|
|
51
|
+
### 3. Apply translation
|
|
52
|
+
|
|
53
|
+
```sh
|
|
54
|
+
hias tfo src/views myNamespace
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Locale files are written to `.hias/lang/myNamespace/`. If `replaceOriginalFile` is `true`, source files are overwritten in place.
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## Commands
|
|
62
|
+
|
|
63
|
+
### `create <project>` (alias: `crt`)
|
|
64
|
+
|
|
65
|
+
Create a project from a framework template.
|
|
66
|
+
|
|
67
|
+
An interactive prompt will list all available frameworks. After selection, the template is downloaded from Gitee and placed into `<project>/`.
|
|
68
|
+
|
|
69
|
+
```sh
|
|
70
|
+
hias create my-app
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
**Available frameworks:**
|
|
74
|
+
|
|
75
|
+
| Name | Description |
|
|
76
|
+
| ------------ | --------------------------- |
|
|
77
|
+
| `vue2` | Vue 2 template |
|
|
78
|
+
| `vue3` | Vue 3 template |
|
|
79
|
+
| `vue-ts` | Vue 3 + TypeScript template |
|
|
80
|
+
| `uni-vite` | uni-app + Vite template |
|
|
81
|
+
| `nuxt-web` | Nuxt.js web template |
|
|
82
|
+
| `vue-screen` | Vue data screen template |
|
|
83
|
+
| `react` | React JSX template |
|
|
84
|
+
| `react-ts` | React TypeScript template |
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
### `adv <name> [options]`
|
|
89
|
+
|
|
90
|
+
Add a Vue component file.
|
|
91
|
+
|
|
92
|
+
```sh
|
|
93
|
+
hias adv Demo -d src/components
|
|
94
|
+
hias adv index -d src/views/demo
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### `adr <name> [options]`
|
|
98
|
+
|
|
99
|
+
Add a React JSX component file.
|
|
100
|
+
|
|
101
|
+
```sh
|
|
102
|
+
hias adr Demo -d src/components
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### `adrt <name> [options]`
|
|
106
|
+
|
|
107
|
+
Add a React TSX component file.
|
|
108
|
+
|
|
109
|
+
```sh
|
|
110
|
+
hias adrt Demo -d src/components
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### `adrd <name> [options]`
|
|
114
|
+
|
|
115
|
+
Add a Redux JSX store file.
|
|
116
|
+
|
|
117
|
+
```sh
|
|
118
|
+
hias adrd useDemoStore -d src/store/modules
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### `adrdt <name> [options]`
|
|
122
|
+
|
|
123
|
+
Add a Redux TSX store file.
|
|
124
|
+
|
|
125
|
+
```sh
|
|
126
|
+
hias adrdt useDemoStore -d src/store/modules
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
#### Common options for component commands
|
|
130
|
+
|
|
131
|
+
| Option | Description |
|
|
132
|
+
| ------------------- | ----------------------------------------------------------------------------- |
|
|
133
|
+
| `-d, --dest <path>` | Target folder. Defaults to `src/components`. Accepts Windows backslash paths. |
|
|
134
|
+
|
|
135
|
+
If `name` is `index`, the component file is named after the parent folder instead.
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
### `close-port <ports...>`
|
|
140
|
+
|
|
141
|
+
Kill processes occupying one or more ports.
|
|
142
|
+
|
|
143
|
+
```sh
|
|
144
|
+
hias close-port 8076 8077
|
|
145
|
+
hias close-port 8076,8077
|
|
146
|
+
hias close-port 3000
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Supports both space-separated and comma-separated port lists. Works on Windows (`netstat` + `taskkill`), macOS, and Linux (`lsof` + `kill`).
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
### `lang [language]`
|
|
154
|
+
|
|
155
|
+
Set or view the CLI language.
|
|
156
|
+
|
|
157
|
+
```sh
|
|
158
|
+
hias lang zh-CN
|
|
159
|
+
hias lang en
|
|
160
|
+
hias lang -l # show current language
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
| Option | Description |
|
|
164
|
+
| ------------ | ------------------------------------- |
|
|
165
|
+
| `-l, --list` | Display the currently active language |
|
|
166
|
+
|
|
167
|
+
Supported languages: `en`, `zh-CN`.
|
|
168
|
+
|
|
169
|
+
Language preference is stored in `~/.hias-cli/config.json`.
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
### Translation Commands
|
|
174
|
+
|
|
175
|
+
The translation system extracts Chinese text from source files, replaces it with `$t()` i18n calls, and generates locale JSON files. Supports Baidu Translate API and Tencent Cloud TMT API.
|
|
176
|
+
|
|
177
|
+
#### `tf [file] [name]`
|
|
178
|
+
|
|
179
|
+
Translate a single file.
|
|
180
|
+
|
|
181
|
+
```sh
|
|
182
|
+
hias tf src/views/index.vue vue
|
|
183
|
+
hias tf src/views/index.vue vue --verbose
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
| Argument / Option | Description |
|
|
187
|
+
| -------------------- | -------------------------------------------------------------------------------------------------------------------------- |
|
|
188
|
+
| `file` (positional) | Path to the file to translate |
|
|
189
|
+
| `name` (positional) | i18n namespace key (defaults to parent directory name) |
|
|
190
|
+
| `-n, --name <name>` | Alternative way to specify the namespace |
|
|
191
|
+
| `--dry-run` | Preview changes without modifying files (shows line-level diff, prompts to apply) |
|
|
192
|
+
| `-v, --verbose` | Show detailed per-file logs instead of a progress spinner |
|
|
193
|
+
| `--show-extractions` | Only display all extracted Chinese texts with file paths and positions, without performing translation or making API calls |
|
|
194
|
+
|
|
195
|
+
**Supported file types:** `.vue`, `.js`, `.ts`, `.jsx`, `.tsx`, `.json`
|
|
196
|
+
|
|
197
|
+
#### `tfo [folder] [name]`
|
|
198
|
+
|
|
199
|
+
Recursively translate all supported files in a folder.
|
|
200
|
+
|
|
201
|
+
```sh
|
|
202
|
+
hias tfo src/views views
|
|
203
|
+
hias tfo src/views views --verbose
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
| Argument / Option | Description |
|
|
207
|
+
| --------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
|
|
208
|
+
| `folder` (positional) | Path to the folder |
|
|
209
|
+
| `name` (positional) | i18n namespace key (defaults to folder name) |
|
|
210
|
+
| `-n, --name <name>` | Alternative way to specify the namespace |
|
|
211
|
+
| `--dry-run` | Preview changes without modifying files (shows line-level diff, prompts to apply) |
|
|
212
|
+
| `-v, --verbose` | Show detailed per-file logs instead of a progress spinner |
|
|
213
|
+
| `--exclude <pattern>` | Exclude files matching a glob pattern (e.g. `**/*.test.js`, `node_modules/**`). Uses minimatch. Can be specified multiple times. |
|
|
214
|
+
| `--show-extractions` | Only display all extracted Chinese texts with file paths and positions, without performing translation or making API calls |
|
|
215
|
+
|
|
216
|
+
#### `setting`
|
|
217
|
+
|
|
218
|
+
Generate a project-level translation config file.
|
|
219
|
+
|
|
220
|
+
```sh
|
|
221
|
+
hias setting
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
Creates `.hias/setting.json` in the current project directory.
|
|
225
|
+
|
|
226
|
+
#### `global-setting`
|
|
227
|
+
|
|
228
|
+
Generate a global translation config file.
|
|
229
|
+
|
|
230
|
+
```sh
|
|
231
|
+
hias global-setting
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
Creates or updates `~/.hias-cli/config.json`. Preserves any existing `language` setting.
|
|
235
|
+
|
|
236
|
+
#### `clear-config`
|
|
237
|
+
|
|
238
|
+
Remove the global config directory `~/.hias-cli`.
|
|
239
|
+
|
|
240
|
+
```sh
|
|
241
|
+
hias clear-config
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
To fully uninstall the CLI and remove user config, run:
|
|
245
|
+
|
|
246
|
+
```sh
|
|
247
|
+
hias uninstall -g
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
This command first runs `hias clear-config`, then runs `npm uninstall @ansstory/hias -g`. npm v7+ no longer runs the old `preuninstall` / `postuninstall` lifecycle scripts during package removal, so `npm uninstall` alone will not delete config files in the home directory.
|
|
251
|
+
|
|
252
|
+
#### `gitignore`
|
|
253
|
+
|
|
254
|
+
Add `.hias` to the project's `.gitignore` file. Creates `.gitignore` if it doesn't exist, or appends the entry if it already exists.
|
|
255
|
+
|
|
256
|
+
```sh
|
|
257
|
+
hias gitignore
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
After running, the `.gitignore` file will contain an entry for `.hias`.
|
|
261
|
+
|
|
262
|
+
---
|
|
263
|
+
|
|
264
|
+
#### `rollback`
|
|
265
|
+
|
|
266
|
+
Restore files from the last translation operation and clean up generated output.
|
|
267
|
+
|
|
268
|
+
Each translation run creates a snapshot in `.hias/.langbackup/<timestamp>_<name>/`. Running `rollback` restores the most recent snapshot and removes it, preserving older snapshots for further step-by-step rollback.
|
|
269
|
+
|
|
270
|
+
```sh
|
|
271
|
+
hias rollback
|
|
272
|
+
hias rollback --list # list available backups
|
|
273
|
+
hias rollback --name 20250101_120000_vue # rollback a specific backup
|
|
274
|
+
hias rollback --keep 3 # keep only the 3 most recent backups, remove older ones
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
**Behavior:** When `replaceOriginalFile` was `true`, original source files are restored; when it was `false`, only the output directory `.hias/lang/<name>/` is removed.
|
|
278
|
+
|
|
279
|
+
**`--keep` behavior:** Backups are sorted by directory name (timestamp), the oldest ones are removed until only N remain. No action if total backups ≤ N.
|
|
280
|
+
|
|
281
|
+
| Option | Description |
|
|
282
|
+
| ---------------- | ------------------------------------------------------ |
|
|
283
|
+
| `-l, --list` | List all available backups |
|
|
284
|
+
| `--name <name>` | Rollback a specific backup by name |
|
|
285
|
+
| `--keep <count>` | Keep only the N most recent backups, remove older ones |
|
|
286
|
+
|
|
287
|
+
---
|
|
288
|
+
|
|
289
|
+
## Configuration
|
|
290
|
+
|
|
291
|
+
### Config Cascade
|
|
292
|
+
|
|
293
|
+
Translation settings are resolved in the following priority order:
|
|
294
|
+
|
|
295
|
+
1. **Project-level** — `.hias/setting.json` in the current working directory
|
|
296
|
+
2. **Global** — `~/.hias-cli/config.json` (created by `hias global-setting`)
|
|
297
|
+
3. **Defaults** — hardcoded defaults (shown below)
|
|
298
|
+
|
|
299
|
+
### Setting File Format
|
|
300
|
+
|
|
301
|
+
```json
|
|
302
|
+
{
|
|
303
|
+
"translationSetting": {
|
|
304
|
+
"locales": ["zh-CN", "en-US"],
|
|
305
|
+
"outDir": ".hias/lang",
|
|
306
|
+
"fallbackToKey": true,
|
|
307
|
+
"replaceOriginalFile": false,
|
|
308
|
+
"provider": "tencent",
|
|
309
|
+
"_provider_hint": "'baidu','tencent'",
|
|
310
|
+
"i18nCallTemplate": "$t",
|
|
311
|
+
"extensions": [".vue", ".js", ".ts", ".jsx", ".tsx", ".json"],
|
|
312
|
+
"appId": "",
|
|
313
|
+
"secretKey": ""
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
### Configuration Fields
|
|
319
|
+
|
|
320
|
+
| Field | Type | Default | Description |
|
|
321
|
+
| --------------------- | ---------- | -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
322
|
+
| `locales` | `string[]` | `["zh-CN", "en-US"]` | Locale code list. **First entry is the source language**, the rest are target languages. E.g. `["zh-CN", "en-US", "ja-JP", "ko-KR"]` generates English, Japanese, and Korean locale files in one pass |
|
|
323
|
+
| `outDir` | `string` | `".hias/lang"` | Output directory for generated locale files and translated copies |
|
|
324
|
+
| `fallbackToKey` | `boolean` | `true` | Whether to generate keys when translation API is unavailable |
|
|
325
|
+
| `replaceOriginalFile` | `boolean` | `false` | When `true`, overwrites source files in place (no copy to `outDir`) |
|
|
326
|
+
| `provider` | `string` | `"tencent"` | Translation provider: `"baidu"` or `"tencent"` |
|
|
327
|
+
| `i18nCallTemplate` | `string` | `"$t"` | i18n function name. When containing `{{key}}`, it's replaced with `namespace.subKey`; otherwise the function wraps it as `$t('key')` |
|
|
328
|
+
| `extensions` | `string[]` | — | Override supported file extensions (e.g. `[".vue", ".ts"]`). Defaults to all supported types |
|
|
329
|
+
| `appId` | `string` | `""` | Baidu AppId or Tencent SecretId |
|
|
330
|
+
| `secretKey` | `string` | `""` | Baidu SecretKey or Tencent SecretKey |
|
|
331
|
+
|
|
332
|
+
### Translation Providers
|
|
333
|
+
|
|
334
|
+
| Provider | `provider` value | `appId` | `secretKey` |
|
|
335
|
+
| ----------------- | ---------------- | ---------------- | ----------------- |
|
|
336
|
+
| Baidu Translate | `"baidu"` | Baidu AppId | Baidu SecretKey |
|
|
337
|
+
| Tencent Cloud TMT | `"tencent"` | Tencent SecretId | Tencent SecretKey |
|
|
338
|
+
|
|
339
|
+
Leave both `appId` and `secretKey` empty to use fallback mode (Chinese text is used as-is for both key and value in locale files).
|
|
340
|
+
|
|
341
|
+
> **Config validation:** Settings are automatically validated when loaded (e.g., `locales` must be an array, `provider` must be a supported enum value, `appId`/`secretKey` must be strings). Invalid values trigger a warning and are reset to defaults without interrupting the workflow.
|
|
342
|
+
|
|
343
|
+
### API Provider Setup
|
|
344
|
+
|
|
345
|
+
#### Baidu Translate
|
|
346
|
+
|
|
347
|
+
1. Visit [Baidu Translate Open Platform](https://fanyi-api.baidu.com/) and register
|
|
348
|
+
2. Create an application to get **AppId** and **SecretKey**
|
|
349
|
+
3. Set `"provider": "baidu"` in config
|
|
350
|
+
|
|
351
|
+
#### Tencent Cloud TMT
|
|
352
|
+
|
|
353
|
+
1. Visit [Tencent Cloud TMT](https://console.cloud.tencent.com/tmt) and enable the service
|
|
354
|
+
2. Create an API key to get **SecretId** (→ `appId`) and **SecretKey**
|
|
355
|
+
3. Set `"provider": "tencent"` in config
|
|
356
|
+
|
|
357
|
+
---
|
|
358
|
+
|
|
359
|
+
## Output Structure
|
|
360
|
+
|
|
361
|
+
After translation, the following directory structure is created (assuming `locales: ["zh-CN", "en-US", "ja-JP"]`):
|
|
362
|
+
|
|
363
|
+
```
|
|
364
|
+
.hias/
|
|
365
|
+
├── setting.json # project-level config
|
|
366
|
+
├── lang/
|
|
367
|
+
│ └── <namespace>/
|
|
368
|
+
│ ├── zh-CN.json # source locale
|
|
369
|
+
│ ├── en-US.json # target locale ①
|
|
370
|
+
│ ├── ja-JP.json # target locale ②
|
|
371
|
+
│ └── <file>.vue # translated copy (only if replaceOriginalFile=false)
|
|
372
|
+
├── .translation-cache.json # translation cache (auto-generated)
|
|
373
|
+
└── .langbackup/
|
|
374
|
+
└── <timestamp>_<namespace>/
|
|
375
|
+
└── <file>.vue.bak # original file backup
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
Locale files use a nested `{ namespace: { key: value } }` format, making them ready for use with `vue-i18n` or similar libraries via module registration.
|
|
379
|
+
|
|
380
|
+
---
|
|
381
|
+
|
|
382
|
+
## Translation Behavior
|
|
383
|
+
|
|
384
|
+
### Source Code Extraction
|
|
385
|
+
|
|
386
|
+
The tool scans source files and extracts Chinese text from:
|
|
387
|
+
|
|
388
|
+
- **Quoted strings**: `'中文'`, `"中文"`, `` `中文{expr}文` `` (template literals with expressions are split, only static Chinese segments extracted)
|
|
389
|
+
- **Vue templates**: `{{ '中文' }}`, `<div>中文</div>`, `:title="'中文'"`
|
|
390
|
+
- **Vue complex expressions**: `{{ isHidden || '中文' }}`, `{{ isHidden ?? '中文' }}` (extracts inline quoted strings from expressions)
|
|
391
|
+
- **Vue directives**: `v-if="text1 == '中文'"`, `v-for="..."` (extracts inline strings from directive expressions)
|
|
392
|
+
- **JSX/TSX text nodes**: `<span>中文 {name}</span>` (mixed text with expressions supported)
|
|
393
|
+
- **JSX/TSX attributes**: `<div title="中文">` or `<div title={'中文'}>`
|
|
394
|
+
- **JSON values**: `"key": "中文值"`
|
|
395
|
+
- **Plain HTML attributes**: `<div title="兴趣">` in Vue templates
|
|
396
|
+
|
|
397
|
+
Comments (`//`, `/* */`, `<!-- -->`) are correctly skipped. `data-*` and `aria-*` attributes are excluded.
|
|
398
|
+
|
|
399
|
+
### Replacement Pattern
|
|
400
|
+
|
|
401
|
+
| Context | Before | After |
|
|
402
|
+
| -------------------------- | ------------------------- | -------------------------------------------------- |
|
|
403
|
+
| Vue template text node | `<div>兴趣</div>` | `<div>{{ $t('demo.interest') }}</div>` |
|
|
404
|
+
| Vue template interpolation | `{{ '兴趣' }}` | `{{ $t('demo.interest') }}` |
|
|
405
|
+
| Vue complex expression | <code>{{ isHidden || '兴趣' }}</code> | <code>{{ isHidden || $t('demo.interest') }}</code> |
|
|
406
|
+
| Vue directive expression | `v-if="text1 == '文本'"` | `v-if="text1 == $t('demo.text')"` |
|
|
407
|
+
| Vue script / JS / TS | `'兴趣'` | `$t('demo.interest')` |
|
|
408
|
+
| JSX text node | `<div>兴趣</div>` | `<div>{$t('demo.interest')}</div>` |
|
|
409
|
+
| JSX attribute | `<div title="兴趣">` | `<div title={$t('demo.interest')}>` |
|
|
410
|
+
| Vue v-bind attribute | `<div :title="'兴趣'">` | `<div :title="$t('demo.interest')">` |
|
|
411
|
+
| Template literal | `` `中文 ${name} 测试` `` | `` `$t('demo.chinese') ${name} $t('demo.test')` `` |
|
|
412
|
+
| JSON value | `"兴趣"` | `"interest"` (replaced with translation directly) |
|
|
413
|
+
|
|
414
|
+
### Locale File Format
|
|
415
|
+
|
|
416
|
+
**When translation succeeds** (English-based keys, truncated to 40 characters):
|
|
417
|
+
|
|
418
|
+
```json
|
|
419
|
+
// zh-CN.json
|
|
420
|
+
{ "demo": { "interest": "兴趣", "test": "测试" } }
|
|
421
|
+
// en-US.json
|
|
422
|
+
{ "demo": { "interest": "interest", "test": "test" } }
|
|
423
|
+
// ja-JP.json (if locales includes ja-JP)
|
|
424
|
+
{ "demo": { "interest": "興味", "test": "テスト" } }
|
|
425
|
+
```
|
|
426
|
+
|
|
427
|
+
**When translation fails** (auto-generated short keys from Chinese, truncated to 40 characters):
|
|
428
|
+
|
|
429
|
+
```json
|
|
430
|
+
// zh-CN.json and en-US.json
|
|
431
|
+
{ "demo": { "提起妈妈的手_一股酸痛便涌上心头": "提起妈妈的手,一股酸痛便涌上心头...", "test": "测试" } }
|
|
432
|
+
```
|
|
433
|
+
|
|
434
|
+
### Key Generation Rules
|
|
435
|
+
|
|
436
|
+
| Scenario | Source | Key Generation | Max Length |
|
|
437
|
+
| ------------ | ------------------ | --------------------------------------- | ---------- |
|
|
438
|
+
| API success | Translated English | snake_case of translation | 40 chars |
|
|
439
|
+
| API fallback | Original Chinese | first-line punctuation → `_`, truncated | 40 chars |
|
|
440
|
+
|
|
441
|
+
Keys are deduplicated: if two texts produce the same truncated key, `_1`, `_2`, etc. are appended.
|
|
442
|
+
|
|
443
|
+
### Translation API Fallback Warning
|
|
444
|
+
|
|
445
|
+
When the translation API call fails (network error, invalid credentials, or rate limit), the tool logs a warning message to the console, e.g.:
|
|
446
|
+
|
|
447
|
+
```
|
|
448
|
+
⚠ Translation API failed, falling back to Chinese keys for this batch
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
It then falls back to Chinese-based auto-generated keys (see [Key Generation Rules](#key-generation-rules) above). This ensures the i18n migration can proceed even without API connectivity.
|
|
452
|
+
|
|
453
|
+
> **Per-text fallback:** If some texts in a batch succeed while others fail, only the failed texts use fallback mode — successful texts still use English keys. This prevents a single failure from degrading the entire batch to Chinese keys.
|
|
454
|
+
|
|
455
|
+
### Translation Cache
|
|
456
|
+
|
|
457
|
+
Successful API translation results are cached to `.hias/.translation-cache.json`. The next time the same text is encountered (regardless of namespace), it's served from cache, avoiding redundant network requests and API costs.
|
|
458
|
+
|
|
459
|
+
- Cache is keyed by original text with target language as sub-key: `{ "text": { "en": "translated" } }`
|
|
460
|
+
- Corrupted or malformed cache files are silently ignored without affecting the normal flow
|
|
461
|
+
- Writes are deferred (`setImmediate`) to avoid blocking the translation pipeline
|
|
462
|
+
|
|
463
|
+
### Unused Translation Cleanup
|
|
464
|
+
|
|
465
|
+
After replacing Chinese text with `$t()` calls, the tool checks existing locale JSON files and **removes keys that are no longer referenced anywhere in the source code**. This prevents locale files from accumulating stale entries over time.
|
|
466
|
+
|
|
467
|
+
Cleanup runs against the same namespace used for the current translation operation, and only affects keys that have zero references across all scanned source files.
|
|
468
|
+
|
|
469
|
+
### Namespace Normalization
|
|
470
|
+
|
|
471
|
+
Existing `$t('oldNamespace.key')` calls in source files are automatically updated to the current namespace name during translation.
|
|
472
|
+
|
|
473
|
+
### Dry-Run Mode
|
|
474
|
+
|
|
475
|
+
When `--dry-run` is specified, the tool shows a line-level diff of all changes without actually modifying files. After the preview, it prompts `Apply changes? (y/N)` — entering `y` or `yes` executes the changes, anything else cancels.
|
|
476
|
+
|
|
477
|
+
### `i18nCallTemplate` Customization
|
|
478
|
+
|
|
479
|
+
The `i18nCallTemplate` field controls the i18n function name and call format:
|
|
480
|
+
|
|
481
|
+
| Template Value | Generated Output |
|
|
482
|
+
| ---------------------------- | ------------------------------------------- |
|
|
483
|
+
| `"$t"` (default) | `$t('demo.interest')` |
|
|
484
|
+
| `"$te"` | `$te('demo.interest')` |
|
|
485
|
+
| `"{{key}}"` | `demo.interest` (raw key, no function call) |
|
|
486
|
+
| `"t('{{key}}')"` | `t('demo.interest')` |
|
|
487
|
+
| `"i18n.global.t('{{key}}')"` | `i18n.global.t('demo.interest')` |
|
|
488
|
+
|
|
489
|
+
When the template **contains** `{{key}}`, it's a template string where `{{key}}` is replaced with `namespace.subKey`. When it does **not** contain `{{key}}`, it wraps as `template('namespace.subKey')`.
|
|
490
|
+
|
|
491
|
+
### Workflow Tips
|
|
492
|
+
|
|
493
|
+
- **Always run `--dry-run` first** when trying translation on a new codebase to verify the extraction results
|
|
494
|
+
- **Use `tfo` with a single file's parent folder** for targeted translation: `hias tfo src/views/MyComponent myComp`
|
|
495
|
+
- **Use `--exclude` to skip config or generated files**: `hias tfo src/views views --exclude "**/*.test.js" --exclude node_modules`
|
|
496
|
+
- **Use separate namespaces per module** to keep locale files small and focused. For example, `src/views/user/` → namespace `user`, `src/views/admin/` → namespace `admin`
|
|
497
|
+
- **Run rollback after verifying** if `replaceOriginalFile` was on: `hias rollback`
|
|
498
|
+
- **Multiple rollbacks**: each `rollback` undoes one snapshot. Run repeatedly to go back further
|
|
499
|
+
- **Re-running translation**: existing `$t()` calls are stripped before re-extraction, so running twice is safe and will only add new translations for any remaining Chinese text
|
|
500
|
+
|
|
501
|
+
---
|
|
502
|
+
|
|
503
|
+
## Global Config
|
|
504
|
+
|
|
505
|
+
The global config file is located at `~/.hias-cli/config.json` and is shared by both the language setting and translation settings:
|
|
506
|
+
|
|
507
|
+
```json
|
|
508
|
+
{
|
|
509
|
+
"language": "zh-CN",
|
|
510
|
+
"translationSetting": {
|
|
511
|
+
"locales": ["zh-CN", "en-US"],
|
|
512
|
+
"outDir": ".hias/lang",
|
|
513
|
+
"fallbackToKey": true,
|
|
514
|
+
"replaceOriginalFile": false,
|
|
515
|
+
"provider": "tencent",
|
|
516
|
+
"_provider_hint": "'baidu','tencent'",
|
|
517
|
+
"i18nCallTemplate": "$t",
|
|
518
|
+
"extensions": [".vue", ".js", ".ts", ".jsx", ".tsx", ".json"],
|
|
519
|
+
"appId": "",
|
|
520
|
+
"secretKey": ""
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
```
|
|
524
|
+
|
|
525
|
+
Managed by:
|
|
526
|
+
|
|
527
|
+
- **`hias lang <language>`** — sets `language`
|
|
528
|
+
- **`hias global-setting`** — creates/updates `translationSetting`
|
|
529
|
+
- **`hias clear-config`** — removes `~/.hias-cli`
|
|
530
|
+
- **`hias uninstall -g`** — runs `hias clear-config`, then uninstalls the global package
|
|
531
|
+
|
|
532
|
+
---
|
|
533
|
+
|
|
534
|
+
## All Commands Reference
|
|
535
|
+
|
|
536
|
+
| Command | Alias | Description |
|
|
537
|
+
| ----------------------- | ----- | ----------------------------------------- |
|
|
538
|
+
| `create <project>` | `crt` | Create project from framework template |
|
|
539
|
+
| `adv <name>` | – | Add Vue component |
|
|
540
|
+
| `adr <name>` | – | Add React JSX component |
|
|
541
|
+
| `adrt <name>` | – | Add React TSX component |
|
|
542
|
+
| `adrd <name>` | – | Add Redux JSX store |
|
|
543
|
+
| `adrdt <name>` | – | Add Redux TSX store |
|
|
544
|
+
| `close-port <ports...>` | – | Kill processes on ports |
|
|
545
|
+
| `lang [language]` | – | Set or view CLI language |
|
|
546
|
+
| `tf [file] [name]` | – | Translate a single file |
|
|
547
|
+
| `tfo [folder] [name]` | – | Translate all files in a folder |
|
|
548
|
+
| `setting` | – | Generate project-level translation config |
|
|
549
|
+
| `global-setting` | – | Generate global translation config |
|
|
550
|
+
| `gitignore` | – | Add `.hias` to `.gitignore` |
|
|
551
|
+
| `rollback` | – | Roll back the last translation operation |
|