scan-debug-skill 1.0.7 → 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/js/SKILL.md CHANGED
@@ -1,27 +1,27 @@
1
- ---
2
- name: js-sonar-repair
3
- description: JavaScript/TypeScript 代码 SonarQube 扫描问题修复指南,涵盖代码规范、框架最佳实践及安全漏洞修复。
4
- ---
5
-
6
- # Sonar JS/TS 代码质量与安全修复技能
7
-
8
- 此技能用于指导 AI 助手协助用户修复 SonarQube 及奇安信安全扫描发现的 JavaScript/TypeScript 代码问题。
9
-
10
- ## 核心原则
11
- 1. **直接高效**:直接给出修复后的完整代码片段,**始终保持中文输出**。
12
- 2. **详细注释**:代码逻辑必须包含详细的中文注释(每一步流程),变量和引入也需注释用途。
13
- 3. **安全优先**:严格遵循 SonarQube 安全热点和奇安信漏洞扫描标准,避免敏感信息泄露。
14
- 4. **规范统一**:异步操作统一使用 Promise/async/await 并强制捕获异常。
15
- 5. **模块化建议**:建议使用 ES6 Class 组织代码(特别是 API 封装),分离业务逻辑与组件交互(此为建议非强制)。
16
-
17
- ## 技能索引
18
-
19
- ### 基础规范
20
- - 注释与文档规范 (JSDoc, 详细逻辑注释, 变量注释) → 详见 [comments-documentation](reference/comments-documentation.md)
21
- - JS/TS 通用最佳实践 (ES6 Class, 异步处理, 日志规范) → 详见 [js-ts-best-practices](reference/js-ts-best-practices.md)
22
- - 代码命名与工程规范 (目录命名, 变量命名, Hooks) → 详见 [naming-conventions](reference/naming-conventions.md)
23
-
24
- ### 安全合规
25
- - 安全漏洞与合规性 (XSS, 敏感信息, 堆栈泄露) → 详见 [security-compliance](reference/security-compliance.md)
26
-
27
-
1
+ ---
2
+ name: js-sonar-repair
3
+ description: JavaScript/TypeScript 代码 SonarQube 扫描问题修复指南,涵盖代码规范、框架最佳实践及安全漏洞修复。
4
+ ---
5
+
6
+ # Sonar JS/TS 代码质量与安全修复技能
7
+
8
+ 此技能用于指导 AI 助手协助用户修复 SonarQube 及奇安信安全扫描发现的 JavaScript/TypeScript 代码问题。
9
+
10
+ ## 核心原则
11
+ 1. **直接高效**:直接给出修复后的完整代码片段,**始终保持中文输出**。
12
+ 2. **详细注释**:代码逻辑必须包含详细的中文注释(每一步流程),变量和引入也需注释用途。
13
+ 3. **安全优先**:严格遵循 SonarQube 安全热点和奇安信漏洞扫描标准,避免敏感信息泄露。
14
+ 4. **规范统一**:异步操作统一使用 Promise/async/await 并强制捕获异常。
15
+ 5. **模块化建议**:建议使用 ES6 Class 组织代码(特别是 API 封装),分离业务逻辑与组件交互(此为建议非强制)。
16
+
17
+ ## 技能索引
18
+
19
+ ### 基础规范
20
+ - 注释与文档规范 (JSDoc, 详细逻辑注释, 变量注释) → 详见 [comments-documentation](reference/comments-documentation.md)
21
+ - JS/TS 通用最佳实践 (ES6 Class, 异步处理, 日志规范) → 详见 [js-ts-best-practices](reference/js-ts-best-practices.md)
22
+ - 代码命名与工程规范 (目录命名, 变量命名, Hooks) → 详见 [naming-conventions](reference/naming-conventions.md)
23
+
24
+ ### 安全合规
25
+ - 安全漏洞与合规性 (XSS, 敏感信息, 堆栈泄露) → 详见 [security-compliance](reference/security-compliance.md)
26
+
27
+
@@ -1,44 +1,44 @@
1
- # 注释与文档规范
2
-
3
- ## 规则详情
4
- * **语言**:所有注释必须使用 **中文**。
5
- * **JSDoc**:导出的函数、类、接口必须包含 JSDoc 注释,说明 `@param` (参数)、`@returns` (返回值) 和 `@throws` (异常)。
6
- * **详细逻辑注释**:
7
- * **流程注释**:代码逻辑的每一个关键步骤和流程分支,都必须有详细的中文单行注释 `//` 说明其意图和处理逻辑。
8
- * **变量/引入注释**:所有引入的模块 (`import`) 和定义的关键变量 (`const`, `let`),必须在其上方或右侧添加注释,说明其用途或来源。
9
- * **非显而易见的修复原因**:对于为了修复 Sonar 问题而做的特殊改动,必须注释说明原因。
10
-
11
- ## 示例
12
- ```javascript
13
- // 引入日期处理工具库
14
- import { format } from 'date-fns';
15
-
16
- /**
17
- * 计算两个日期之间的天数差
18
- * @description 用于计算合同期限或逾期天数
19
- * @param {Date} startDate - 开始日期对象
20
- * @param {Date} endDate - 结束日期对象
21
- * @returns {number} - 两个日期之间的天数差(绝对值)
22
- * @throws {Error} - 如果参数不是有效的日期对象抛出异常
23
- */
24
- function getDaysDiff(startDate, endDate) {
25
- // 1. 参数校验:检查传入的日期对象是否有效
26
- if (!startDate || !endDate) {
27
- // 如果日期无效,返回 0 天
28
- return 0;
29
- }
30
-
31
- // 2. 获取时间戳:将日期对象转换为毫秒数
32
- const startObj = startDate.getTime(); // 开始时间毫秒数
33
- const endObj = endDate.getTime(); // 结束时间毫秒数
34
-
35
- // 3. 计算差值:取绝对值以确保结果为正数
36
- const diffTime = Math.abs(endObj - startObj);
37
-
38
- // 定义一天的毫秒数常量
39
- const ONE_DAY_MS = 1000 * 60 * 60 * 24;
40
-
41
- // 4. 转换天数:向上取整,不足一天按一天计算(根据业务需求调整)
42
- return Math.ceil(diffTime / ONE_DAY_MS);
43
- }
44
- ```
1
+ # 注释与文档规范
2
+
3
+ ## 规则详情
4
+ * **语言**:所有注释必须使用 **中文**。
5
+ * **JSDoc**:导出的函数、类、接口必须包含 JSDoc 注释,说明 `@param` (参数)、`@returns` (返回值) 和 `@throws` (异常)。
6
+ * **详细逻辑注释**:
7
+ * **流程注释**:代码逻辑的每一个关键步骤和流程分支,都必须有详细的中文单行注释 `//` 说明其意图和处理逻辑。
8
+ * **变量/引入注释**:所有引入的模块 (`import`) 和定义的关键变量 (`const`, `let`),必须在其上方或右侧添加注释,说明其用途或来源。
9
+ * **非显而易见的修复原因**:对于为了修复 Sonar 问题而做的特殊改动,必须注释说明原因。
10
+
11
+ ## 示例
12
+ ```javascript
13
+ // 引入日期处理工具库
14
+ import { format } from 'date-fns';
15
+
16
+ /**
17
+ * 计算两个日期之间的天数差
18
+ * @description 用于计算合同期限或逾期天数
19
+ * @param {Date} startDate - 开始日期对象
20
+ * @param {Date} endDate - 结束日期对象
21
+ * @returns {number} - 两个日期之间的天数差(绝对值)
22
+ * @throws {Error} - 如果参数不是有效的日期对象抛出异常
23
+ */
24
+ function getDaysDiff(startDate, endDate) {
25
+ // 1. 参数校验:检查传入的日期对象是否有效
26
+ if (!startDate || !endDate) {
27
+ // 如果日期无效,返回 0 天
28
+ return 0;
29
+ }
30
+
31
+ // 2. 获取时间戳:将日期对象转换为毫秒数
32
+ const startObj = startDate.getTime(); // 开始时间毫秒数
33
+ const endObj = endDate.getTime(); // 结束时间毫秒数
34
+
35
+ // 3. 计算差值:取绝对值以确保结果为正数
36
+ const diffTime = Math.abs(endObj - startObj);
37
+
38
+ // 定义一天的毫秒数常量
39
+ const ONE_DAY_MS = 1000 * 60 * 60 * 24;
40
+
41
+ // 4. 转换天数:向上取整,不足一天按一天计算(根据业务需求调整)
42
+ return Math.ceil(diffTime / ONE_DAY_MS);
43
+ }
44
+ ```
@@ -1,155 +1,155 @@
1
- # JS/TS 通用最佳实践
2
-
3
- ## 规则详情
4
- * **模块化与组织 (Class-based)**:
5
- * 优先使用 ES6 Class 语法进行模块化组织,特别是 API 请求封装。
6
- * 通过继承 (`extends`) 实现常量和通用逻辑的复用。
7
- * **异步处理 (Async/Await)**:
8
- * 统一采用 `Promise` / `async/await` 进行异步处理。
9
- * **强制捕获异常**:所有 Promise 调用必须追加 `.catch()` 方法或包裹在 `try...catch` 中。
10
- * **异常处理规范**:
11
- * **严禁空 Catch**:`catch` 块或 `.catch()` 回调中必须包含处理逻辑,禁止留空。
12
- * **安全打印**:遵循 [安全合规规范 - 日志安全](security-compliance.md) 要求,严禁打印堆栈信息。
13
- * **日志与异常 (Logging)**:
14
- * **分级打印**:建议根据场景正确使用 `console.error()` (错误), `console.warn()` (警告), `console.info()` (信息)。
15
- * **异常输出**:避免打印冗余的堆栈详情 (`error.stack`),仅输出关键信息(如 `***方法报错/接口请求失败`)。
16
- * **强类型判断**:始终使用 `===` 和 `!==` 代替 `==` 和 `!=`,避免隐式类型转换带来的 Bug。
17
- * **变量声明**:优先使用 `const`,其次使用 `let`,**严禁使用 `var`**。
18
- * **认知复杂度 (Cognitive Complexity)**:当 Sonar 提示函数复杂度过高(通常 > 15)时,须逻辑拆分为多个职责单一的子函数(此为建议非强制)。
19
- * **魔法数字 (Magic Numbers)**:避免直接使用无意义的数字(0 和 1 除外),应将其定义为具名常量。
20
- * **冗余条件判断**:当 `if` 和 `else` 分支执行逻辑完全一致时,应移除条件判断,直接执行公共逻辑。
21
- * **空值检查 (Null Safety)**:在访问对象的深层属性前,必须进行非空检查,推荐使用可选链操作符 (`?.`) 和空值合并操作符 (`??`),避免 "Cannot read property of undefined" 错误。
22
- * **性能优化**:
23
- * **正则表达式预编译**:避免在循环内创建 `RegExp` 实例,应提取到循环外部或模块作用域。
24
- * **避免嵌套循环**:3 层以上的嵌套循环(O(n³))必须优化,建议使用 `flatMap` 或 Map 索引。
25
- * **字符串拼接**:循环内避免使用 `+=` 拼接大量字符串,应使用数组 `push` 后 `join`。
26
- * **异常处理**:
27
- * **禁止 Finally Return**:`finally` 块中严禁使用 `return`,否则会覆盖 `try/catch` 中的异常抛出。
28
- * **流程控制**:禁止使用异常(try-catch)来处理正常的业务流程控制(如判断 JSON 格式,应先用正则预判)。
29
- * **状态管理**:
30
- * **状态回滚**:前端乐观更新(Optimistic UI)时,若请求失败必须回滚状态。
31
- * **避免全局锁**:避免使用单一的全局 `loading` 状态控制并发请求,应使用独立的 loading 变量。
32
-
33
- ## 示例:认知复杂度与魔法数字
34
-
35
- **场景**:Sonar 提示 "Refactor this function to reduce its Cognitive Complexity" 及 "Replace this constant value 86400000 with a name"。
36
-
37
- **修复后代码**:
38
- ```javascript
39
- // 定义常量,消除魔法数字
40
- const ONE_DAY_MS = 24 * 60 * 60 * 1000;
41
-
42
- /**
43
- * 检查日期是否在明天之后
44
- * @param {Date} date - 待检查的日期对象
45
- * @returns {boolean} - 如果日期有效且在一天之后,返回 true
46
- */
47
- function isDateFuture(date) {
48
- // 1. 参数校验:确保日期对象存在
49
- if (!date) {
50
- return false;
51
- }
52
-
53
- // 2. 逻辑判断:计算时间差
54
- const thresholdTime = Date.now() + ONE_DAY_MS;
55
-
56
- // 3. 返回结果:判断是否超过阈值
57
- return date.getTime() > thresholdTime;
58
- }
59
- ```
60
-
61
- ## 示例:冗余条件判断
62
-
63
- **场景**:Sonar 提示 "This 'if' block is equivalent to the 'else' block",即 `if` 和 `else` 分支执行了完全相同的逻辑。
64
-
65
- **修复后代码**:
66
- ```javascript
67
- /**
68
- * 处理页面跳转
69
- * @description 无论用户是否登录,点击该按钮都跳转到首页
70
- */
71
- function handleRedirect() {
72
- // Compliant: 移除冗余的条件判断
73
- // 修复前:
74
- // if (isLoggedIn) {
75
- // navigateTo('/home');
76
- // } else {
77
- // navigateTo('/home');
78
- // }
79
-
80
- // 修复后:直接执行通用逻辑
81
- navigateTo('/home');
82
- }
83
- ```
84
-
85
- ## 示例:空指针异常修复
86
-
87
- **场景**:代码运行时抛出 "TypeError: Cannot read property 'name' of undefined",或 Sonar 提示可能存在空指针访问风险。
88
-
89
- **修复后代码**:
90
- ```javascript
91
- /**
92
- * 获取用户显示名称
93
- * @param {Object} user - 用户对象
94
- * @returns {string} - 用户名称或默认值
95
- */
96
- function getUserDisplayName(user) {
97
- // Non-Compliant: 如果 user 或 user.profile 为空,将导致程序崩溃
98
- // return user.profile.name;
99
-
100
- // Compliant: 使用可选链 (?.) 安全访问,并提供默认值 (??)
101
- return user?.profile?.name ?? '未知用户';
102
- }
103
-
104
- /**
105
- * 处理订单列表
106
- * @param {Array} orders - 订单数组
107
- */
108
- function processOrders(orders) {
109
- // Compliant: 确保 orders 存在且为数组后再进行遍历
110
- if (Array.isArray(orders) && orders.length > 0) {
111
- orders.forEach(order => {
112
- console.log(`订单ID: ${order?.id}`);
113
- });
114
- }
115
- }
116
- ```
117
-
118
- ## 示例:性能优化与异常处理
119
-
120
- **场景**:Sonar 提示 "Regular expressions should not be created in a loop" 或 "Jump statements should not occur in finally blocks"。
121
-
122
- **修复后代码**:
123
- ```javascript
124
- // 1. 正则预编译
125
- // Non-Compliant: 循环内重复创建正则
126
- // items.forEach(item => { if (new RegExp('^\\d{4}').test(item)) ... })
127
-
128
- // Compliant: 提取为常量
129
- const DATE_PATTERN = /^\d{4}-\d{2}-\d{2}$/;
130
- items.forEach(item => {
131
- if (DATE_PATTERN.test(item.date)) { /* ... */ }
132
- });
133
-
134
- // 2. 字符串拼接优化
135
- // Non-Compliant: 使用 += 拼接
136
- // let html = ""; list.forEach(i => html += `<li>${i}</li>`);
137
-
138
- // Compliant: 使用 Array.join
139
- const html = list.map(i => `<li>${i}</li>`).join("");
140
-
141
- // 3. 禁止 Finally Return
142
- async function submitData() {
143
- try {
144
- await api.post('/submit');
145
- } catch (error) {
146
- console.error('提交失败', error);
147
- return Promise.reject(error);
148
- } finally {
149
- // Non-Compliant: return true; // 这会吞掉上面的 reject
150
-
151
- // Compliant: 仅做清理工作
152
- this.loading = false;
153
- }
154
- }
155
- ```
1
+ # JS/TS 通用最佳实践
2
+
3
+ ## 规则详情
4
+ * **模块化与组织 (Class-based)**:
5
+ * 优先使用 ES6 Class 语法进行模块化组织,特别是 API 请求封装。
6
+ * 通过继承 (`extends`) 实现常量和通用逻辑的复用。
7
+ * **异步处理 (Async/Await)**:
8
+ * 统一采用 `Promise` / `async/await` 进行异步处理。
9
+ * **强制捕获异常**:所有 Promise 调用必须追加 `.catch()` 方法或包裹在 `try...catch` 中。
10
+ * **异常处理规范**:
11
+ * **严禁空 Catch**:`catch` 块或 `.catch()` 回调中必须包含处理逻辑,禁止留空。
12
+ * **安全打印**:遵循 [安全合规规范 - 日志安全](security-compliance.md) 要求,严禁打印堆栈信息。
13
+ * **日志与异常 (Logging)**:
14
+ * **分级打印**:建议根据场景正确使用 `console.error()` (错误), `console.warn()` (警告), `console.info()` (信息)。
15
+ * **异常输出**:避免打印冗余的堆栈详情 (`error.stack`),仅输出关键信息(如 `***方法报错/接口请求失败`)。
16
+ * **强类型判断**:始终使用 `===` 和 `!==` 代替 `==` 和 `!=`,避免隐式类型转换带来的 Bug。
17
+ * **变量声明**:优先使用 `const`,其次使用 `let`,**严禁使用 `var`**。
18
+ * **认知复杂度 (Cognitive Complexity)**:当 Sonar 提示函数复杂度过高(通常 > 15)时,须逻辑拆分为多个职责单一的子函数(此为建议非强制)。
19
+ * **魔法数字 (Magic Numbers)**:避免直接使用无意义的数字(0 和 1 除外),应将其定义为具名常量。
20
+ * **冗余条件判断**:当 `if` 和 `else` 分支执行逻辑完全一致时,应移除条件判断,直接执行公共逻辑。
21
+ * **空值检查 (Null Safety)**:在访问对象的深层属性前,必须进行非空检查,推荐使用可选链操作符 (`?.`) 和空值合并操作符 (`??`),避免 "Cannot read property of undefined" 错误。
22
+ * **性能优化**:
23
+ * **正则表达式预编译**:避免在循环内创建 `RegExp` 实例,应提取到循环外部或模块作用域。
24
+ * **避免嵌套循环**:3 层以上的嵌套循环(O(n³))必须优化,建议使用 `flatMap` 或 Map 索引。
25
+ * **字符串拼接**:循环内避免使用 `+=` 拼接大量字符串,应使用数组 `push` 后 `join`。
26
+ * **异常处理**:
27
+ * **禁止 Finally Return**:`finally` 块中严禁使用 `return`,否则会覆盖 `try/catch` 中的异常抛出。
28
+ * **流程控制**:禁止使用异常(try-catch)来处理正常的业务流程控制(如判断 JSON 格式,应先用正则预判)。
29
+ * **状态管理**:
30
+ * **状态回滚**:前端乐观更新(Optimistic UI)时,若请求失败必须回滚状态。
31
+ * **避免全局锁**:避免使用单一的全局 `loading` 状态控制并发请求,应使用独立的 loading 变量。
32
+
33
+ ## 示例:认知复杂度与魔法数字
34
+
35
+ **场景**:Sonar 提示 "Refactor this function to reduce its Cognitive Complexity" 及 "Replace this constant value 86400000 with a name"。
36
+
37
+ **修复后代码**:
38
+ ```javascript
39
+ // 定义常量,消除魔法数字
40
+ const ONE_DAY_MS = 24 * 60 * 60 * 1000;
41
+
42
+ /**
43
+ * 检查日期是否在明天之后
44
+ * @param {Date} date - 待检查的日期对象
45
+ * @returns {boolean} - 如果日期有效且在一天之后,返回 true
46
+ */
47
+ function isDateFuture(date) {
48
+ // 1. 参数校验:确保日期对象存在
49
+ if (!date) {
50
+ return false;
51
+ }
52
+
53
+ // 2. 逻辑判断:计算时间差
54
+ const thresholdTime = Date.now() + ONE_DAY_MS;
55
+
56
+ // 3. 返回结果:判断是否超过阈值
57
+ return date.getTime() > thresholdTime;
58
+ }
59
+ ```
60
+
61
+ ## 示例:冗余条件判断
62
+
63
+ **场景**:Sonar 提示 "This 'if' block is equivalent to the 'else' block",即 `if` 和 `else` 分支执行了完全相同的逻辑。
64
+
65
+ **修复后代码**:
66
+ ```javascript
67
+ /**
68
+ * 处理页面跳转
69
+ * @description 无论用户是否登录,点击该按钮都跳转到首页
70
+ */
71
+ function handleRedirect() {
72
+ // Compliant: 移除冗余的条件判断
73
+ // 修复前:
74
+ // if (isLoggedIn) {
75
+ // navigateTo('/home');
76
+ // } else {
77
+ // navigateTo('/home');
78
+ // }
79
+
80
+ // 修复后:直接执行通用逻辑
81
+ navigateTo('/home');
82
+ }
83
+ ```
84
+
85
+ ## 示例:空指针异常修复
86
+
87
+ **场景**:代码运行时抛出 "TypeError: Cannot read property 'name' of undefined",或 Sonar 提示可能存在空指针访问风险。
88
+
89
+ **修复后代码**:
90
+ ```javascript
91
+ /**
92
+ * 获取用户显示名称
93
+ * @param {Object} user - 用户对象
94
+ * @returns {string} - 用户名称或默认值
95
+ */
96
+ function getUserDisplayName(user) {
97
+ // Non-Compliant: 如果 user 或 user.profile 为空,将导致程序崩溃
98
+ // return user.profile.name;
99
+
100
+ // Compliant: 使用可选链 (?.) 安全访问,并提供默认值 (??)
101
+ return user?.profile?.name ?? '未知用户';
102
+ }
103
+
104
+ /**
105
+ * 处理订单列表
106
+ * @param {Array} orders - 订单数组
107
+ */
108
+ function processOrders(orders) {
109
+ // Compliant: 确保 orders 存在且为数组后再进行遍历
110
+ if (Array.isArray(orders) && orders.length > 0) {
111
+ orders.forEach(order => {
112
+ console.log(`订单ID: ${order?.id}`);
113
+ });
114
+ }
115
+ }
116
+ ```
117
+
118
+ ## 示例:性能优化与异常处理
119
+
120
+ **场景**:Sonar 提示 "Regular expressions should not be created in a loop" 或 "Jump statements should not occur in finally blocks"。
121
+
122
+ **修复后代码**:
123
+ ```javascript
124
+ // 1. 正则预编译
125
+ // Non-Compliant: 循环内重复创建正则
126
+ // items.forEach(item => { if (new RegExp('^\\d{4}').test(item)) ... })
127
+
128
+ // Compliant: 提取为常量
129
+ const DATE_PATTERN = /^\d{4}-\d{2}-\d{2}$/;
130
+ items.forEach(item => {
131
+ if (DATE_PATTERN.test(item.date)) { /* ... */ }
132
+ });
133
+
134
+ // 2. 字符串拼接优化
135
+ // Non-Compliant: 使用 += 拼接
136
+ // let html = ""; list.forEach(i => html += `<li>${i}</li>`);
137
+
138
+ // Compliant: 使用 Array.join
139
+ const html = list.map(i => `<li>${i}</li>`).join("");
140
+
141
+ // 3. 禁止 Finally Return
142
+ async function submitData() {
143
+ try {
144
+ await api.post('/submit');
145
+ } catch (error) {
146
+ console.error('提交失败', error);
147
+ return Promise.reject(error);
148
+ } finally {
149
+ // Non-Compliant: return true; // 这会吞掉上面的 reject
150
+
151
+ // Compliant: 仅做清理工作
152
+ this.loading = false;
153
+ }
154
+ }
155
+ ```
@@ -1,78 +1,78 @@
1
- # 代码命名与工程规范
2
-
3
- ## 规则详情
4
-
5
- * **目录与文件命名**:
6
- * 统一使用 `kebab-case`(短横线连接),例如 `src/components/user-list.js`、`src/hooks/use-user-info.ts`。
7
- * 组件/类文件可使用 `PascalCase`(大驼峰)或 `kebab-case`,但项目中应保持统一。
8
- * **组件/类命名**:
9
- * 文件名:`UserList.ts` 或 `user-list.ts`。
10
- * 类名:`UserList` (PascalCase)。
11
- * 使用时:`new UserList()` (PascalCase)。
12
- * **变量与函数命名**:
13
- * 变量/函数:使用 `camelCase`(小驼峰),例如 `userInfo`, `fetchData`。
14
- * 常量:使用 `UPPER_CASE`(全大写下划线),例如 `MAX_COUNT`, `API_BASE_URL`。
15
- * **方法名**:必须使用动宾结构,例如 `getUserList` (获取), `handleSubmit` (处理), `isFinished` (判断)。
16
- * **布尔变量**:推荐以 `is`, `has`, `should` 开头,例如 `isVisible`, `hasError`。
17
- * **类型与接口命名**:
18
- * 统一使用 `PascalCase`(大驼峰),例如 `interface UserInfo {}`, `type ApiResponse = {}`。
19
- * 不要使用下划线命名法(如 `user_info`)。
20
- * **Hooks 命名**:
21
- * 文件名:`use-auth.ts` (kebab-case)。
22
- * 导出函数:`useAuth` (camelCase,以 use 开头)。
23
-
24
- ## 示例:命名规范
25
-
26
- **场景**:Sonar 提示 "Rename this file to match the regular expression..." 或 "Identifier 'xxx' does not match usage"。
27
-
28
- **修复后代码**:
29
- ```typescript
30
- // 文件名: src/hooks/use-user-info.ts
31
-
32
- // Non-Compliant: 接口命名不规范
33
- // interface user_info {}
34
-
35
- // Compliant: 接口使用 PascalCase
36
- export interface UserInfo {
37
- id: number;
38
- name: string;
39
- }
40
-
41
- // Non-Compliant: 函数名无动宾结构
42
- // function data() {}
43
-
44
- // Compliant: 函数名动宾结构,变量小驼峰
45
- export function useUserInfo() {
46
- const isLoading = ref(false);
47
-
48
- async function fetchUserData() {
49
- // ...
50
- }
51
-
52
- return {
53
- isLoading,
54
- fetchUserData
55
- };
56
- }
57
- ```
58
-
59
- ## 示例:目录结构分层
60
-
61
- **场景**:代码耦合度高,API 请求散落在组件中。
62
-
63
- **修复后代码**:
64
- ```javascript
65
- // ❌ Non-Compliant: API 请求写在组件/UI层内部
66
- // src/components/UserList.ts
67
- const res = await axios.post("/api/user/list", data);
68
-
69
- // ✅ Compliant: API 调用集中在 src/api/,UI层只调用服务
70
- // src/api/user.ts
71
- export function fetchUserList(data) {
72
- return request.post('/api/user/list', data);
73
- }
74
-
75
- // src/components/UserList.ts
76
- import { fetchUserList } from "@/api/user";
77
- const res = await fetchUserList(data);
78
- ```
1
+ # 代码命名与工程规范
2
+
3
+ ## 规则详情
4
+
5
+ * **目录与文件命名**:
6
+ * 统一使用 `kebab-case`(短横线连接),例如 `src/components/user-list.js`、`src/hooks/use-user-info.ts`。
7
+ * 组件/类文件可使用 `PascalCase`(大驼峰)或 `kebab-case`,但项目中应保持统一。
8
+ * **组件/类命名**:
9
+ * 文件名:`UserList.ts` 或 `user-list.ts`。
10
+ * 类名:`UserList` (PascalCase)。
11
+ * 使用时:`new UserList()` (PascalCase)。
12
+ * **变量与函数命名**:
13
+ * 变量/函数:使用 `camelCase`(小驼峰),例如 `userInfo`, `fetchData`。
14
+ * 常量:使用 `UPPER_CASE`(全大写下划线),例如 `MAX_COUNT`, `API_BASE_URL`。
15
+ * **方法名**:必须使用动宾结构,例如 `getUserList` (获取), `handleSubmit` (处理), `isFinished` (判断)。
16
+ * **布尔变量**:推荐以 `is`, `has`, `should` 开头,例如 `isVisible`, `hasError`。
17
+ * **类型与接口命名**:
18
+ * 统一使用 `PascalCase`(大驼峰),例如 `interface UserInfo {}`, `type ApiResponse = {}`。
19
+ * 不要使用下划线命名法(如 `user_info`)。
20
+ * **Hooks 命名**:
21
+ * 文件名:`use-auth.ts` (kebab-case)。
22
+ * 导出函数:`useAuth` (camelCase,以 use 开头)。
23
+
24
+ ## 示例:命名规范
25
+
26
+ **场景**:Sonar 提示 "Rename this file to match the regular expression..." 或 "Identifier 'xxx' does not match usage"。
27
+
28
+ **修复后代码**:
29
+ ```typescript
30
+ // 文件名: src/hooks/use-user-info.ts
31
+
32
+ // Non-Compliant: 接口命名不规范
33
+ // interface user_info {}
34
+
35
+ // Compliant: 接口使用 PascalCase
36
+ export interface UserInfo {
37
+ id: number;
38
+ name: string;
39
+ }
40
+
41
+ // Non-Compliant: 函数名无动宾结构
42
+ // function data() {}
43
+
44
+ // Compliant: 函数名动宾结构,变量小驼峰
45
+ export function useUserInfo() {
46
+ const isLoading = ref(false);
47
+
48
+ async function fetchUserData() {
49
+ // ...
50
+ }
51
+
52
+ return {
53
+ isLoading,
54
+ fetchUserData
55
+ };
56
+ }
57
+ ```
58
+
59
+ ## 示例:目录结构分层
60
+
61
+ **场景**:代码耦合度高,API 请求散落在组件中。
62
+
63
+ **修复后代码**:
64
+ ```javascript
65
+ // ❌ Non-Compliant: API 请求写在组件/UI层内部
66
+ // src/components/UserList.ts
67
+ const res = await axios.post("/api/user/list", data);
68
+
69
+ // ✅ Compliant: API 调用集中在 src/api/,UI层只调用服务
70
+ // src/api/user.ts
71
+ export function fetchUserList(data) {
72
+ return request.post('/api/user/list', data);
73
+ }
74
+
75
+ // src/components/UserList.ts
76
+ import { fetchUserList } from "@/api/user";
77
+ const res = await fetchUserList(data);
78
+ ```