HarmonyOS掌上记账APP开发实践第80篇:Code Linter 与代码质量 — 使用 code-linter.json5 保障工程规范
Code Linter 与代码质量 — 使用 code-linter.json5 保障工程规范

文章简介
在团队协作开发中,统一的代码风格和质量标准是保障工程可维护性的基石。HarmonyOS 提供了 Code Linter 工具,通过 code-linter.json5 配置文件定义代码风格和安全规则。MoneyTrack 项目配置了包括 @typescript-eslint 规则、安全规则和性能规则在内的完整 Linter 体系。本文从 Linter 在开发流程中的定位出发,详细解析配置语法、规则体系、命名规范以及 CI/CD 集成方案。
Linter 在开发流程中的位置
Code Linter 应嵌入到从编码到发布的整个流程中,形成自动化的质量门禁:
核心知识点
1. code-linter.json5 完整配置
code-linter.json5 是 Code Linter 的核心配置文件,位于项目根目录下。MoneyTrack 项目的完整配置如下:
{
// 指定要扫描的文件匹配模式
"files": ["**/*.ets", "**/*.ts"],
// 排除不需要扫描的目录
"ignore": [
"**/ohosTest/**/*",
"**/test/**/*",
"**/build/**/*",
"**/oh_modules/**/*"
],
// 启用规则集(plugin 前缀表示来自插件)
"ruleSet": [
"plugin:@performance/recommended",
"plugin:@typescript-eslint/recommended",
"plugin:@hw-stylistic/recommended",
"plugin:@security/recommended"
],
// 细粒度规则配置(覆盖 ruleSet 中的默认行为)
"rules": {
// ===== 安全规则 =====
"@security/no-unsafe-aes": "error",
"@security/no-hardcoded-credentials": "error",
// ===== TypeScript 类型规则 =====
"@typescript-eslint/await-thenable": "error",
"@typescript-eslint/no-floating-promises": "error",
"@typescript-eslint/explicit-member-accessibility": ["error", {
"accessibility": "explicit",
"overrides": { "constructors": "no-public" }
}],
"@typescript-eslint/consistent-type-definitions": ["error", "interface"],
"@typescript-eslint/prefer-readonly": "warn",
// ===== 命名规范 =====
"@typescript-eslint/naming-convention": ["error", {
"selector": "default",
"format": ["camelCase", "UPPER_CASE"]
}, {
"selector": "variable",
"format": ["camelCase", "UPPER_CASE"]
}, {
"selector": "function",
"format": ["camelCase"]
}, {
"selector": "class",
"format": ["PascalCase"]
}, {
"selector": "interface",
"format": ["PascalCase"]
}, {
"selector": "enum",
"format": ["PascalCase"]
}, {
"selector": "enumMember",
"format": ["UPPER_CASE"]
}, {
"selector": "memberLike",
"modifiers": ["private"],
"format": ["camelCase"],
"leadingUnderscore": "require"
}],
// ===== 风格规则 =====
"@hw-stylistic/quotes": ["error", "single"],
"@hw-stylistic/semi": ["error", "always"],
"@hw-stylistic/comma-dangle": ["error", "always-multiline"],
"@hw-stylistic/indent": ["error", 2],
"@hw-stylistic/max-len": ["warn", { "code": 120 }],
// ===== 变量声明规则 =====
"init-declarations": ["error", "always"]
}
}
配置字段说明:
| 字段 | 类型 | 说明 |
|---|---|---|
files |
string[] |
文件匹配模式,决定哪些文件被扫描 |
ignore |
string[] |
排除模式,跳过不需要检查的目录 |
ruleSet |
string[] |
引用的预定义规则集,支持 plugin: 前缀 |
rules |
object |
单个规则的启用/禁用/配置,值可为 "off"、"warn"、"error" 或配置数组 |
2. @typescript-eslint 常用规则详解
| 规则名 | 级别 | 作用 | 违反示例 | 正确示例 |
|---|---|---|---|---|
await-thenable |
error | 禁止 await 非 Promise 值 | await someString |
await somePromise |
no-floating-promises |
error | 禁止未处理的 Promise | asyncFunc() |
await asyncFunc() |
explicit-member-accessibility |
error | 要求显式成员访问修饰符 | name: string |
public name: string |
consistent-type-definitions |
error | 强制使用 interface | type User = { id: number } |
interface User { id: number } |
prefer-readonly |
warn | 建议只读成员加 readonly | private id: number |
private readonly id: number |
naming-convention |
error | 强制统一命名规范 | class user_service |
class UserService |
no-unused-vars |
error | 禁止声明未使用的变量 | const x = 1(未使用) |
删除或使用 _x 前缀 |
prefer-optional-chain |
warn | 建议使用可选链 | a && a.b |
a?.b |
3. 命名规范完整要求
MoneyTrack 项目遵循以下命名规范,由 naming-convention 规则强制执行:
| 代码元素 | 规范 | 示例 | 说明 |
|---|---|---|---|
| 变量(普通) | camelCase | userName、billList、totalAmount |
普通变量统一小驼峰 |
| 变量(常量) | UPPER_CASE | MAX_RETRY_COUNT、API_BASE_URL |
全局常量全大写+下划线 |
| 函数/方法 | camelCase | initData()、refreshBill()、getTotalIncome() |
动宾结构,小驼峰 |
| 类 | PascalCase | HomeVM、StatisticsVM、BillRepository |
名词或名词短语 |
| 接口 | PascalCase | IBill、IUserInfo、PageState |
可以是 I 前缀或无前缀 |
| 枚举 | PascalCase | BillType、Category、TransactionStatus |
名词形式 |
| 枚举成员 | UPPER_CASE | EXPENSE、INCOME、PENDING、COMPLETED |
全大写+下划线 |
| 私有成员 | camelCase + _ 前缀 |
_instance、_cacheData、_subscription |
下划线开头表示私有 |
| 类型参数 | PascalCase 单字母 | T、K、V、R |
泛型统一单大写字母 |
项目中的实际应用:
// ✅ 符合规范
const MAX_PAGE_SIZE: number = 50;
let userName: string = '';
class HomeVM {
private readonly _instance: HomeVM;
private _billList: Bill[] = [];
public async initData(): Promise<void> {
// 初始化逻辑
}
public getTotalIncome(): number {
return this._billList.reduce((sum, bill) => sum + bill.amount, 0);
}
}
interface IBill {
id: string;
amount: number;
category: Category;
}
enum Category {
FOOD = 'FOOD',
TRANSPORT = 'TRANSPORT',
ENTERTAINMENT = 'ENTERTAINMENT',
}
// ❌ 违反规范
class home_vm {} // 类必须 PascalCase
function Get_Data() {} // 函数必须 camelCase
let User_Name = 'test'; // 变量必须 camelCase
const max_count = 10; // 常量必须 UPPER_CASE
4. CI/CD 集成
Pre-commit Hook 配置:
在 .husky/pre-commit 中配置提交前自动运行 Linter:
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
# 对暂存的文件运行 Linter
npx code-linter --files="$(git diff --cached --name-only --diff-filter=d | grep -E '\.(ets|ts)$' | tr '\n' ',')"
if [ $? -ne 0 ]; then
echo "❌ Lint 检查未通过,请修复后重新提交"
exit 1
fi
CI 流水线集成(oh-pipeline.json5):
{
"stages": [{
"name": "quality-gate",
"jobs": [{
"name": "code-lint",
"steps": [
{ "name": "安装依赖", "command": "ohpm install" },
{ "name": "运行 Linter", "command": "code-linter --config code-linter.json5" },
{ "name": "运行单元测试", "command": "ohos test --build-type local" }
]
}]
}]
}
最佳实践
-
渐进式启用:不要一次性开启所有规则。先启用核心规则(如命名规范、安全规则),等团队适应后再逐步增加风格类规则,避免大量报错打乱开发节奏。
-
规则覆盖优先级:
rules中的单个规则配置优先级高于ruleSet中的默认配置。在ruleSet基础上通过rules微调,而不需要删除整个规则集。 -
Lint 即文档:将命名规范、代码风格等约定通过 Linter 规则强制执行,而不是写在团队规范文档中。这样新的团队成员不需要记忆大量规则,Linter 会实时提示。
-
CI 门禁:在 CI 流水线中设置 Lint 检查为门禁卡点,Lint 未通过的代码不能合并到主分支。这比依赖开发人员自觉性更可靠。
-
阶段区分:在本地开发和 pre-commit 阶段只对变更文件进行检查(速度快),在 CI 阶段对全量文件扫描(确保全面),两者配合使用。
-
定期审查:每个迭代结束后审查 Linter 报错统计,如果某些规则频繁被违反,考虑是否规则过于严格或不合理,及时调整配置。
推荐参考文档
- HarmonyOS Code Linter 工具文档
- @typescript-eslint 规则参考
- code-linter.json5 配置语法
- 代码审查最佳实践指南
更多推荐



所有评论(0)