scan-debug-skill 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.md +2 -2
- package/SKILL.md +58 -68
- package/bin/install.js +7 -7
- package/css/reference/best-practices.md +38 -20
- package/css/reference/comments-documentation.md +15 -15
- package/css/reference/duplicate-properties.md +16 -16
- package/css/reference/font-family-fallback.md +15 -15
- package/html/SKILL.md +26 -26
- package/html/reference/comments-documentation.md +16 -16
- package/html/reference/form-labels.md +20 -20
- package/html/reference/image-alt-text.md +18 -18
- package/html/reference/security-compliance.md +16 -16
- package/html/reference/semantic-structure.md +43 -43
- package/js/SKILL.md +27 -29
- package/js/reference/comments-documentation.md +44 -44
- package/js/reference/js-ts-best-practices.md +155 -106
- package/js/reference/naming-conventions.md +78 -0
- package/js/reference/security-compliance.md +69 -69
- package/package.json +1 -1
- package/js/reference/framework-vue-react.md +0 -80
package/js/SKILL.md
CHANGED
|
@@ -1,29 +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
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
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,106 +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
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
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
|
+
```
|
|
@@ -0,0 +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,69 +1,69 @@
|
|
|
1
|
-
# 安全合规规范 (Security)
|
|
2
|
-
|
|
3
|
-
## 规则详情
|
|
4
|
-
* **XSS 防范**:
|
|
5
|
-
* 严禁使用 `eval()`、`new Function()`。
|
|
6
|
-
*
|
|
7
|
-
* **敏感信息**:代码中禁止硬编码密码、Token、密钥(AK/SK)、内网 IP 等敏感信息,应通过环境变量或配置接口获取。
|
|
8
|
-
* **日志安全**:
|
|
9
|
-
* 禁止在生产环境日志中输出敏感信息(如密码、Token 等)。
|
|
10
|
-
* **变量命名**:若变量名无明确语义化(如 `data`, `info`, `res`),视为潜在敏感信息禁止直接打印。
|
|
11
|
-
* **异常捕获**:**严禁直接打印 `error.stack` 或完整的 `error` 对象**。如无法确定 `error` 结构则不打印 `error`,必须按照 **模块名 + 方法名 + 错误简述** 的格式输出,防止堆栈信息泄露系统内部结构。
|
|
12
|
-
* **链接安全**:使用 `target="_blank"` 打开外部链接时,必须添加 `rel="noopener noreferrer"` 以防止钓鱼攻击。
|
|
13
|
-
* **正则安全**:确保正则表达式不会导致拒绝服务攻击 (ReDoS)。
|
|
14
|
-
|
|
15
|
-
## 示例:敏感信息处理
|
|
16
|
-
|
|
17
|
-
**场景**:Sonar 提示 "Hardcoded passwords/tokens/keys should not be used"。
|
|
18
|
-
|
|
19
|
-
**修复后代码**:
|
|
20
|
-
```javascript
|
|
21
|
-
// Non-Compliant: 硬编码敏感信息
|
|
22
|
-
// const API_KEY = "sk-123456789";
|
|
23
|
-
|
|
24
|
-
// Compliant: 使用环境变量
|
|
25
|
-
// 说明:确保环境变量在构建或运行时已正确注入
|
|
26
|
-
const API_KEY = process.env.
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
## 示例:日志安全与异常处理
|
|
30
|
-
|
|
31
|
-
**场景**:Sonar/安全扫描提示 "User credentials should not be printed" 或 "Stack traces should not be disclosed"。
|
|
32
|
-
|
|
33
|
-
**修复后代码**:
|
|
34
|
-
```javascript
|
|
35
|
-
/**
|
|
36
|
-
* 处理用户登录
|
|
37
|
-
* @param {string} username - 用户名
|
|
38
|
-
* @param {string} password - 密码
|
|
39
|
-
*/
|
|
40
|
-
async function handleLogin(username, password) {
|
|
41
|
-
try {
|
|
42
|
-
// 1. 敏感信息禁止打印
|
|
43
|
-
// Non-Compliant (敏感数据): console.log(`Attempting login for ${username} with password ${password}`);
|
|
44
|
-
// Non-Compliant (非语义化变量): console.log('Login info:', info); // info 语义不明确,可能包含敏感字段
|
|
45
|
-
console.log(`Attempting login for user: ${username}`); // Compliant: 仅记录明确的非敏感标识
|
|
46
|
-
|
|
47
|
-
await authService.login(username, password);
|
|
48
|
-
|
|
49
|
-
} catch (error) {
|
|
50
|
-
// 2. 异常捕获禁止泄露堆栈
|
|
51
|
-
// Non-Compliant: console.error(error); 或 console.error(error.stack);
|
|
52
|
-
|
|
53
|
-
// Compliant: 仅记录错误来源,不包含详细堆栈
|
|
54
|
-
// 格式要求:模块名 + 方法名 + 错误简述
|
|
55
|
-
console.error('LoginService: handleLogin 方法报错/接口请求失败');
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
## 示例:正则表达式安全 (ReDoS)
|
|
61
|
-
|
|
62
|
-
**场景**:Sonar 提示 "Make sure the regex used here... cannot lead to denial of service"。
|
|
63
|
-
|
|
64
|
-
**修复后代码**:
|
|
65
|
-
```javascript
|
|
66
|
-
// Compliant: 优化正则结构,避免嵌套量词,防止 ReDoS 攻击
|
|
67
|
-
// 说明:匹配一个或多个 'a' 后跟一个 'b'
|
|
68
|
-
const regex = /a+b/;
|
|
69
|
-
```
|
|
1
|
+
# 安全合规规范 (Security)
|
|
2
|
+
|
|
3
|
+
## 规则详情
|
|
4
|
+
* **XSS 防范**:
|
|
5
|
+
* 严禁使用 `eval()`、`new Function()`。
|
|
6
|
+
* 处理用户输入的 HTML 内容时,必须确保内容已经过 DOMPurify 等库的清洗,避免直接插入未过滤的 HTML。
|
|
7
|
+
* **敏感信息**:代码中禁止硬编码密码、Token、密钥(AK/SK)、内网 IP 等敏感信息,应通过环境变量或配置接口获取。
|
|
8
|
+
* **日志安全**:
|
|
9
|
+
* 禁止在生产环境日志中输出敏感信息(如密码、Token 等)。
|
|
10
|
+
* **变量命名**:若变量名无明确语义化(如 `data`, `info`, `res`),视为潜在敏感信息禁止直接打印。
|
|
11
|
+
* **异常捕获**:**严禁直接打印 `error.stack` 或完整的 `error` 对象**。如无法确定 `error` 结构则不打印 `error`,必须按照 **模块名 + 方法名 + 错误简述** 的格式输出,防止堆栈信息泄露系统内部结构。
|
|
12
|
+
* **链接安全**:使用 `target="_blank"` 打开外部链接时,必须添加 `rel="noopener noreferrer"` 以防止钓鱼攻击。
|
|
13
|
+
* **正则安全**:确保正则表达式不会导致拒绝服务攻击 (ReDoS)。
|
|
14
|
+
|
|
15
|
+
## 示例:敏感信息处理
|
|
16
|
+
|
|
17
|
+
**场景**:Sonar 提示 "Hardcoded passwords/tokens/keys should not be used"。
|
|
18
|
+
|
|
19
|
+
**修复后代码**:
|
|
20
|
+
```javascript
|
|
21
|
+
// Non-Compliant: 硬编码敏感信息
|
|
22
|
+
// const API_KEY = "sk-123456789";
|
|
23
|
+
|
|
24
|
+
// Compliant: 使用环境变量
|
|
25
|
+
// 说明:确保环境变量在构建或运行时已正确注入
|
|
26
|
+
const API_KEY = process.env.API_KEY;
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## 示例:日志安全与异常处理
|
|
30
|
+
|
|
31
|
+
**场景**:Sonar/安全扫描提示 "User credentials should not be printed" 或 "Stack traces should not be disclosed"。
|
|
32
|
+
|
|
33
|
+
**修复后代码**:
|
|
34
|
+
```javascript
|
|
35
|
+
/**
|
|
36
|
+
* 处理用户登录
|
|
37
|
+
* @param {string} username - 用户名
|
|
38
|
+
* @param {string} password - 密码
|
|
39
|
+
*/
|
|
40
|
+
async function handleLogin(username, password) {
|
|
41
|
+
try {
|
|
42
|
+
// 1. 敏感信息禁止打印
|
|
43
|
+
// Non-Compliant (敏感数据): console.log(`Attempting login for ${username} with password ${password}`);
|
|
44
|
+
// Non-Compliant (非语义化变量): console.log('Login info:', info); // info 语义不明确,可能包含敏感字段
|
|
45
|
+
console.log(`Attempting login for user: ${username}`); // Compliant: 仅记录明确的非敏感标识
|
|
46
|
+
|
|
47
|
+
await authService.login(username, password);
|
|
48
|
+
|
|
49
|
+
} catch (error) {
|
|
50
|
+
// 2. 异常捕获禁止泄露堆栈
|
|
51
|
+
// Non-Compliant: console.error(error); 或 console.error(error.stack);
|
|
52
|
+
|
|
53
|
+
// Compliant: 仅记录错误来源,不包含详细堆栈
|
|
54
|
+
// 格式要求:模块名 + 方法名 + 错误简述
|
|
55
|
+
console.error('LoginService: handleLogin 方法报错/接口请求失败');
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## 示例:正则表达式安全 (ReDoS)
|
|
61
|
+
|
|
62
|
+
**场景**:Sonar 提示 "Make sure the regex used here... cannot lead to denial of service"。
|
|
63
|
+
|
|
64
|
+
**修复后代码**:
|
|
65
|
+
```javascript
|
|
66
|
+
// Compliant: 优化正则结构,避免嵌套量词,防止 ReDoS 攻击
|
|
67
|
+
// 说明:匹配一个或多个 'a' 后跟一个 'b'
|
|
68
|
+
const regex = /a+b/;
|
|
69
|
+
```
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "scan-debug-skill",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.8",
|
|
4
4
|
"description": "A set of code scanning and debugging skills, primarily for quick fixes of common SonarQube and Qianxin issues. | 一套代码扫描与调试技能,主要应用于 SonarQube 和奇安信常见问题的快速修复。",
|
|
5
5
|
"bin": {
|
|
6
6
|
"scan-debug-skill": "./bin/install.js"
|