@zzclub/z-cli 0.5.4 → 0.6.1

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/CHANGELOG.md CHANGED
@@ -1,6 +1,30 @@
1
1
  # Changelog
2
2
 
3
3
 
4
+ ## v0.6.1
5
+
6
+ [compare changes](https://github.com/aatrooox/z-cli/compare/v0.6.0...v0.6.1)
7
+
8
+ ### 📖 Documentation
9
+
10
+ - 更新文档说明 ([259328c](https://github.com/aatrooox/z-cli/commit/259328c))
11
+
12
+ ### ❤️ Contributors
13
+
14
+ - Aatrox <gnakzz@qq.com>
15
+
16
+ ## v0.6.0
17
+
18
+ [compare changes](https://github.com/aatrooox/z-cli/compare/v0.5.4...v0.6.0)
19
+
20
+ ### 🚀 Enhancements
21
+
22
+ - 改造i18n,使其能够直接提取中文 ([bb05eac](https://github.com/aatrooox/z-cli/commit/bb05eac))
23
+
24
+ ### ❤️ Contributors
25
+
26
+ - Aatrox <gnakzz@qq.com>
27
+
4
28
  ## v0.5.4
5
29
 
6
30
  [compare changes](https://github.com/aatrooox/z-cli/compare/v0.5.3...v0.5.4)
package/README.md CHANGED
@@ -31,12 +31,95 @@ npm i -g @zzclub/z-cli
31
31
 
32
32
  ## i18n 规则说明
33
33
 
34
- 1. 只提取 `.vue` 文件
35
- 2. 匹配规则,如:$t('i18n.module-name.placeholder.month') => `/\$t\(['"]i18n\.([^'"]+)['"]\)/g`
36
- 1. 默认忽略 common。如 $t('i18n.common.placeholder.month') 会被忽略
37
- 2. 以逗号分割,第一位 i18n 是固定的。 第二位为 文件名。 最后一位为属性key。 第二至最后之间,为 object 的 key
38
- 3. 最后的文件名称为 `module-name.js` 内容为 `{ placeholder: { month: "month"}} `
39
- 4. 保存位置如果没传。就会保存在 `.vue` 同级目录下
34
+ ### 文件
35
+
36
+ 只提取 `.vue` 文件
37
+
38
+ ### `$t`解析及生成规则
39
+
40
+ 提取正则: `/\$t\(['"]i18n\.([^'"]+)['"]\)/g`
41
+
42
+ 举例:
43
+
44
+ ```js
45
+ $t('i18n.module-name.placeholder.month')
46
+ ```
47
+
48
+ - module-name 会被解析为文件名称 => `module-name.js`
49
+ - 后面的内容会被解析为对象的属性 => `{ placeholder: { month: "month"}} `
50
+ - 保存位置如果没传。就会保存在 `.vue` 同级目录下
51
+ - 默认忽略 module-name 为 `common` => `$t('i18n.common.xxx')`
52
+
53
+ ### 中文注释规范及提取规则
54
+
55
+ ```vue
56
+ <template>
57
+ <!--i18n addTitle=你好呀 a=不错 b=叭叭叭 c=哈哈哈 -->
58
+ <CommonEditForm :page-type="pageType" :title-config="titleConfig" :custom-components-code="$t('i18n.monthlyForecast.pageTitle.addTitle')" :is-out="2">
59
+ <div>{{ $t('i18n.monthlyForecast.form.a') }}</div>
60
+ <div>{{ $t('i18n.monthlyForecast.form.b') }}</div>
61
+ <!--i18n select=真棒 -->
62
+ <div>{{ $t('i18n.monthlyForecast.placeholder.select') }}</div>
63
+ </CommonEditForm>
64
+
65
+ </template>
66
+
67
+ <!-- js 区域 -->
68
+ <script>
69
+ import {formatDate} from "@/common/utils"
70
+ import CommonEditForm from "@/pages/ifpf/costForecast/monthlyForecast/views/common-edit-form.vue"
71
+
72
+ export default {
73
+ name: 'ifpfExchangeRateMaintainAdd',
74
+ components:{
75
+ CommonEditForm,
76
+ },
77
+ data() {
78
+ return {
79
+ pageType: 'edit',
80
+ titleConfig: {
81
+ title: this.$t('i18n.monthlyForecast.pageTitle.addTitle'),//测试
82
+ icon: this.$t('i18n.monthlyForecast.pageTitle.icon'), // 图标
83
+ date: formatDate.formatDateOnly(new Date()),
84
+ info: this.$t('i18n.monthlyForecast.pageTitle.addInfo')//你好
85
+ },
86
+ };
87
+ }
88
+ };
89
+ </script>
90
+
91
+ ```
92
+
93
+ 解析后:
94
+
95
+ ```js
96
+ export default {
97
+ pageTitle: {
98
+ addTitle: "测试",
99
+ icon: "图标",
100
+ addInfo: "你好"
101
+ },
102
+ form: {
103
+ a: "不错",
104
+ b: "叭叭叭"
105
+ },
106
+ placeholder: {
107
+ select: "真棒"
108
+ }
109
+ }
110
+ ```
111
+ - template 中的注释,比如以 `<!--i18n` 开头
112
+ - template 中的中文内容以 `空格` 分割,以 `=` 号拼接key=value, 如 `addTitle=你好呀 a=不错`
113
+ - template 中支持多个注释信息
114
+ - template 中的key=value和$t中最后一个key对应
115
+ - js 中支持两种注释信息提取
116
+ - `$t()` 后紧跟 `//` , `//`后的中文内容都被视为默认值
117
+ - `$t()` 后存在 `,` 、`空格` 这两种符号,然后再跟 `//`, `//`后的中文内容都被视为默认值
118
+
119
+ **解析完成后,自行把文件挪到到 zh-CN 文件夹下**
120
+
121
+ **然后使用 `translate` 命令进行中译英**
122
+
40
123
 
41
124
  ## 翻译功能配置说明
42
125
  ### 初始化翻译平台appId和key
@@ -131,8 +214,10 @@ zz translate -d ./demo
131
214
  ├── test2.js
132
215
  └── test3.js
133
216
 
134
-
135
217
  ```
218
+
219
+ **翻译时可能存在翻译失败的情况,重新运行 translate 命令即可**
220
+
136
221
  ## 压缩图片
137
222
 
138
223
  使用help命令查看所有支持的功能
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zzclub/z-cli",
3
- "version": "0.5.4",
3
+ "version": "0.6.1",
4
4
  "description": "all-in-one 工具箱,专为提升日常及工作效率而生",
5
5
  "main": "src/index.js",
6
6
  "type": "module",
@@ -68,14 +68,14 @@ const i18nCmd = {
68
68
  for (const file of filePaths) {
69
69
  const content = fs.readFileSync(file, 'utf-8');
70
70
  const fileName = path.basename(file, '.vue');
71
- const i18nKeys = extractI18nKeys(content);
71
+ const { keys: i18nKeys, commentMap } = extractI18nKeys(content);
72
72
 
73
73
  if (i18nKeys.length > 0) {
74
74
  file_spinner.succeed(`从 ${chalk.yellow(fileName)} 中提取了 ${chalk.green(i18nKeys.length)} 个国际化键值`);
75
75
 
76
76
  // 处理每个提取的键值
77
77
  for (const key of i18nKeys) {
78
- await processI18nKey(key, i18nMap);
78
+ await processI18nKey(key, i18nMap, commentMap);
79
79
  }
80
80
  }
81
81
  }
@@ -109,7 +109,7 @@ const i18nCmd = {
109
109
 
110
110
  const content = fs.readFileSync(filePath, 'utf-8');
111
111
  const fileName = path.basename(filePath, '.vue');
112
- const i18nKeys = extractI18nKeys(content);
112
+ const { keys: i18nKeys, commentMap } = extractI18nKeys(content);
113
113
 
114
114
  if (i18nKeys.length > 0) {
115
115
  const i18nMap = {};
@@ -118,7 +118,7 @@ const i18nCmd = {
118
118
 
119
119
  // 处理每个提取的键值
120
120
  for (const key of i18nKeys) {
121
- await processI18nKey(key, i18nMap);
121
+ await processI18nKey(key, i18nMap, commentMap);
122
122
  }
123
123
 
124
124
  // 如果没有指定输出目录,使用当前处理的文件所在目录
@@ -163,25 +163,81 @@ function getAllVueFiles(dirPath, filePaths) {
163
163
  * 从 Vue 文件内容中提取国际化键值
164
164
  * @param {string} content 文件内容
165
165
  * @param {string} ignorePrefix 要忽略的前缀
166
- * @returns {Array} 提取的键值数组
166
+ * @returns {Object} 提取的键值数组和注释映射
167
167
  */
168
168
  function extractI18nKeys(content, ignorePrefix = "common") {
169
+ // 原有正则表达式,提取键名
169
170
  const regex = /\$t\(['"]i18n\.([^'"]+)['"]\)/g;
171
+ // 提取键名和注释中的中文
172
+ const regexWithComment = /\$t\(['"]i18n\.([^'"]+)['"]\)[\s,]*\/\/\s*([\u4e00-\u9fa5].*?)(?=\n|$)/g;
173
+ // 新增:提取HTML注释中的i18n信息
174
+ const regexHtmlComment = /<!--i18n\s+(.*?)-->/g;
175
+
170
176
  const keys = [];
177
+ const commentMap = {}; // 存储键名和对应的注释内容
171
178
  let match;
172
179
 
180
+ // 提取HTML注释中的i18n信息
181
+ while ((match = regexHtmlComment.exec(content)) !== null) {
182
+ const commentContent = match[1].trim();
183
+ // 解析注释内容中的多个键值对
184
+ const keyValuePairs = commentContent.split(/\s+/);
185
+
186
+ for (const pair of keyValuePairs) {
187
+ const [key, value] = pair.split('=');
188
+ if (key && value) {
189
+ // 将简短键(如addTitle)与完整键(如monthlyForecast.pageTitle.addTitle)进行匹配
190
+ // 这里我们需要在后续处理中找到对应的完整键
191
+ commentMap[key] = value;
192
+ }
193
+ }
194
+ }
195
+
196
+ // 提取带注释的国际化键
197
+ while ((match = regexWithComment.exec(content)) !== null) {
198
+ const key = match[1];
199
+ const comment = match[2].trim();
200
+
201
+ // 如果设置了忽略前缀且键以该前缀开头,则跳过
202
+ if (ignorePrefix && key.startsWith(`${ignorePrefix}.`)) {
203
+ continue;
204
+ }
205
+
206
+ keys.push(key);
207
+ // JS注释优先级高于HTML注释
208
+ commentMap[key] = comment;
209
+
210
+ // 同时为简短键名存储注释
211
+ const shortKey = key.split('.').pop();
212
+ if (!commentMap[shortKey]) {
213
+ commentMap[shortKey] = comment;
214
+ }
215
+ }
216
+
217
+ // 提取不带注释的国际化键
173
218
  while ((match = regex.exec(content)) !== null) {
174
219
  const key = match[1];
220
+
175
221
  // 如果设置了忽略前缀且键以该前缀开头,则跳过
176
222
  if (ignorePrefix && key.startsWith(`${ignorePrefix}.`)) {
177
223
  continue;
178
224
  }
225
+
179
226
  keys.push(key);
227
+
228
+ // 检查是否有对应的HTML注释
229
+ const shortKey = key.split('.').pop();
230
+ if (commentMap[shortKey] && !commentMap[key]) {
231
+ commentMap[key] = commentMap[shortKey];
232
+ }
180
233
  }
181
234
 
182
- return [...new Set(keys)]; // 去重
235
+ // 返回去重后的键名数组和注释映射
236
+ return {
237
+ keys: [...new Set(keys)],
238
+ commentMap
239
+ };
183
240
  }
184
-
185
241
  function unquoteKeys(json) {
186
242
  return json.replace(/"(\\[^]|[^\\"])*"\s*:?/g, function (match) {
187
243
  if (/:$/.test(match)) {
@@ -196,8 +252,9 @@ function unquoteKeys(json) {
196
252
  * 处理单个国际化键值
197
253
  * @param {string} key 键值
198
254
  * @param {Object} i18nMap 国际化映射对象
255
+ * @param {Object} commentMap 注释映射
199
256
  */
200
- async function processI18nKey(key, i18nMap) {
257
+ async function processI18nKey(key, i18nMap, commentMap = {}) {
201
258
  // 解析键值 fee-forecast-maintain.placeholder.yearNum
202
259
  const parts = key.split('.');
203
260
 
@@ -223,8 +280,8 @@ async function processI18nKey(key, i18nMap) {
223
280
 
224
281
  // 设置最终的键值
225
282
  if (!current[lastKey]) {
226
- // 使用键名作为默认值
227
- current[lastKey] = lastKey;
283
+ // 如果有注释,使用注释作为值,否则使用键名
284
+ current[lastKey] = commentMap[key] || lastKey;
228
285
  }
229
286
  }
230
287