代码质量

高质量的代码是项目成功的关键。通过代码规范、静态检查和自动化工具,可以显著提升代码的可维护性和可靠性。

代码规范

命名规范

// 变量命名 - 小驼峰
const userName = '东巴文'
const itemCount = 100
const isVisible = true

// 常量命名 - 大写蛇形
const MAX_RETRY_COUNT = 3
const API_BASE_URL = 'https://api.db-w.cn'
const DEFAULT_TIMEOUT = 5000

// 函数命名 - 小驼峰,动词开头
function getUserInfo() {}
function calculateTotal() {}
function handleButtonClick() {}
function validateEmail() {}

// 类命名 - 大驼峰
class UserService {}
class ShoppingCart {}
class EventEmitter {}

// 私有属性/方法 - 下划线前缀
class User {
  constructor() {
    this._id = 1
    this._privateMethod()
  }
  
  _privateMethod() {}
}

// 文件命名
// 组件:PascalCase.js 或 PascalCase.vue
// 工具:camelCase.js
// 常量:UPPER_CASE.js 或 constants.js

// 布尔值命名
const isLoading = true
const hasPermission = false
const canEdit = true
const shouldRender = false
const isValid = true

代码风格

// 缩进:2 空格或 4 空格(团队统一)
function example() {
  const x = 1
  if (x > 0) {
    console.log(x)
  }
}

// 分号:使用或不使用(团队统一)
const a = 1
const b = 2

// 引号:优先使用单引号
const name = '东巴文'
const template = `Hello, ${name}`

// 大括号风格
if (condition) {
  // do something
} else {
  // do other
}

// 空格使用
const sum = a + b
const obj = { name: '东巴文', age: 18 }
const arr = [1, 2, 3]
function fn(a, b) {}

// 空行使用
function fn1() {
  // ...
}

function fn2() {
  // ...
}

// 链式调用
const result = [1, 2, 3]
  .map(x => x * 2)
  .filter(x => x > 2)
  .reduce((a, b) => a + b, 0)

// 长字符串
const longString = 
  '这是一段很长的文字,' +
  '需要分成多行来写。'

const templateString = `
  这是一段多行文字,
  使用模板字符串更清晰。
`

注释规范

/**
 * 计算两个数的和
 * @param {number} a - 第一个数
 * @param {number} b - 第二个数
 * @returns {number} 两数之和
 */
function add(a, b) {
  return a + b
}

/**
 * 用户类
 * @class
 */
class User {
  /**
   * @param {string} name - 用户名
   * @param {number} age - 年龄
   */
  constructor(name, age) {
    this.name = name
    this.age = age
  }
  
  /**
   * 获取用户信息
   * @returns {Object} 用户信息对象
   */
  getInfo() {
    return {
      name: this.name,
      age: this.age
    }
  }
}

// 单行注释
const MAX_SIZE = 100  // 最大尺寸限制

// TODO 注释
// TODO: 实现缓存功能

// FIXME 注释
// FIXME: 这里可能有性能问题

// HACK 注释
// HACK: 临时解决方案,需要后续优化

// 多行注释
/*
 * 这是一段多行注释
 * 用于解释复杂的逻辑
 */

ESLint

ESLint 是 JavaScript 代码检查工具,帮助发现和修复代码问题。

安装配置

# 安装
npm install -D eslint

# 初始化配置
npx eslint --init
// .eslintrc.js
module.exports = {
  // 环境
  env: {
    browser: true,
    node: true,
    es2021: true,
    jest: true
  },
  
  // 继承配置
  extends: [
    'eslint:recommended',
    'plugin:react/recommended',
    'plugin:@typescript-eslint/recommended',
    'prettier'
  ],
  
  // 解析器
  parser: '@typescript-eslint/parser',
  parserOptions: {
    ecmaVersion: 'latest',
    sourceType: 'module',
    ecmaFeatures: {
      jsx: true
    }
  },
  
  // 插件
  plugins: [
    'react',
    '@typescript-eslint'
  ],
  
  // 规则
  rules: {
    // 错误级别:off | warn | error
    'no-unused-vars': 'warn',
    'no-console': 'warn',
    'no-debugger': 'error',
    'no-var': 'error',
    'prefer-const': 'warn',
    'eqeqeq': ['error', 'always'],
    'curly': ['error', 'all'],
    'indent': ['error', 2],
    'quotes': ['error', 'single'],
    'semi': ['error', 'always'],
    'comma-dangle': ['error', 'always-multiline'],
    'arrow-spacing': 'error',
    'no-duplicate-imports': 'error',
    'no-template-curly-in-string': 'error',
    'require-await': 'error',
    'react/react-in-jsx-scope': 'off',
    '@typescript-eslint/no-explicit-any': 'warn'
  },
  
  // 忽略文件
  ignorePatterns: ['node_modules/', 'dist/', '*.config.js'],
  
  // 全局变量
  globals: {
    $: 'readonly',
    jQuery: 'readonly'
  }
}

常用规则

rules: {
  // 可能的错误
  'no-cond-assign': 'error',           // 条件语句中禁止赋值
  'no-console': 'warn',                // 禁止 console
  'no-debugger': 'error',              // 禁止 debugger
  'no-dupe-keys': 'error',             // 禁止重复键
  'no-duplicate-case': 'error',        // 禁止重复 case
  'no-empty': 'error',                 // 禁止空块
  'no-unreachable': 'error',           // 禁止不可达代码
  
  // 最佳实践
  'curly': 'error',                    // 强制大括号
  'default-case': 'warn',              // switch 需要 default
  'eqeqeq': 'error',                   // 使用 ===
  'no-else-return': 'error',           // return 后不需要 else
  'no-empty-function': 'warn',         // 禁止空函数
  'no-eval': 'error',                  // 禁止 eval
  'no-multi-spaces': 'error',          // 禁止多余空格
  'no-param-reassign': 'warn',         // 禁止参数重赋值
  'no-return-await': 'error',          // 禁止不必要的 return await
  'prefer-promise-reject-errors': 'error', // reject 需要 Error
  
  // 变量
  'no-unused-vars': 'warn',            // 禁止未使用变量
  'no-var': 'error',                   // 禁止 var
  'prefer-const': 'error',             // 优先 const
  
  // 风格
  'array-bracket-spacing': 'error',    // 数组括号空格
  'block-spacing': 'error',            // 块内空格
  'brace-style': 'error',              // 大括号风格
  'camelcase': 'error',                // 驼峰命名
  'comma-dangle': 'error',             // 尾逗号
  'comma-spacing': 'error',            // 逗号空格
  'eol-last': 'error',                 // 文件末尾换行
  'indent': 'error',                   // 缩进
  'key-spacing': 'error',              // 键值空格
  'keyword-spacing': 'error',          // 关键字空格
  'no-multiple-empty-lines': 'error',  // 空行数量
  'no-trailing-spaces': 'error',       // 禁止尾随空格
  'object-curly-spacing': 'error',     // 对象花括号空格
  'quotes': 'error',                   // 引号风格
  'semi': 'error',                     // 分号
  'space-before-blocks': 'error',      // 块前空格
  'space-infix-ops': 'error',          // 运算符空格
}

使用方式

# 检查文件
npx eslint src/

# 自动修复
npx eslint src/ --fix

# 指定配置文件
npx eslint src/ -c .eslintrc.custom.js

# 输出格式
npx eslint src/ -f json
npx eslint src/ -f html -o report.html
// package.json
{
  "scripts": {
    "lint": "eslint src/",
    "lint:fix": "eslint src/ --fix"
  }
}

Prettier

Prettier 是代码格式化工具,自动统一代码风格。

安装配置

npm install -D prettier
// .prettierrc.js
module.exports = {
  printWidth: 80,              // 每行最大字符数
  tabWidth: 2,                 // 缩进空格数
  useTabs: false,              // 使用空格缩进
  semi: true,                  // 使用分号
  singleQuote: true,           // 使用单引号
  quoteProps: 'as-needed',     // 对象属性引号
  jsxSingleQuote: false,       // JSX 使用双引号
  trailingComma: 'es5',        // 尾逗号
  bracketSpacing: true,        // 对象花括号空格
  bracketSameLine: false,      // JSX 标签闭合括号
  arrowParens: 'avoid',        // 箭头函数参数括号
  endOfLine: 'lf',             // 换行符
  proseWrap: 'preserve',       // 文本换行
  htmlWhitespaceSensitivity: 'css', // HTML 空白敏感度
  vueIndentScriptAndStyle: false    // Vue 缩进
}

使用方式

# 格式化文件
npx prettier --write src/

# 检查格式
npx prettier --check src/

# 指定配置
npx prettier --write src/ --config .prettierrc.custom.js
// package.json
{
  "scripts": {
    "format": "prettier --write \"src/**/*.{js,jsx,ts,tsx,css,scss,json}\"",
    "format:check": "prettier --check \"src/**/*.{js,jsx,ts,tsx,css,scss,json}\""
  }
}

ESLint 集成

npm install -D eslint-config-prettier eslint-plugin-prettier
// .eslintrc.js
module.exports = {
  extends: [
    'eslint:recommended',
    'prettier'  // 必须放在最后
  ],
  plugins: ['prettier'],
  rules: {
    'prettier/prettier': 'error'
  }
}

Git Hooks

使用 Git Hooks 在提交前自动检查代码。

Husky

# 安装
npm install -D husky lint-staged

# 初始化
npx husky install
npx husky add .husky/pre-commit "npx lint-staged"
// lint-staged.config.js
module.exports = {
  '*.{js,jsx,ts,tsx}': [
    'eslint --fix',
    'prettier --write'
  ],
  '*.{css,scss,less}': [
    'prettier --write'
  ],
  '*.{json,md}': [
    'prettier --write'
  ]
}
// package.json
{
  "scripts": {
    "prepare": "husky install"
  },
  "lint-staged": {
    "*.{js,jsx,ts,tsx}": ["eslint --fix", "prettier --write"],
    "*.{css,scss,json,md}": ["prettier --write"]
  }
}

commitlint

npm install -D @commitlint/cli @commitlint/config-conventional
// commitlint.config.js
module.exports = {
  extends: ['@commitlint/config-conventional'],
  rules: {
    'type-enum': [
      2,
      'always',
      [
        'feat',     // 新功能
        'fix',      // 修复 bug
        'docs',     // 文档
        'style',    // 代码格式
        'refactor', // 重构
        'perf',     // 性能优化
        'test',     // 测试
        'chore',    // 构建/工具
        'revert'    // 回滚
      ]
    ],
    'subject-case': [0]
  }
}
# 添加 commit-msg hook
npx husky add .husky/commit-msg 'npx commitlint --edit $1'

代码复杂度

圈复杂度

// 高圈复杂度 - 难以维护
function processUser(user) {
  if (user) {
    if (user.active) {
      if (user.role === 'admin') {
        if (user.permissions.includes('write')) {
          // ...
        } else {
          // ...
        }
      } else {
        // ...
      }
    } else {
      // ...
    }
  } else {
    // ...
  }
}

// 低圈复杂度 - 易于维护
function processUser(user) {
  if (!user) return handleNoUser()
  if (!user.active) return handleInactiveUser()
  if (user.role === 'admin') return processAdmin(user)
  return processRegularUser(user)
}

函数长度

// 过长的函数 - 拆分
function processOrder(order) {
  // 验证订单
  // 计算价格
  // 应用折扣
  // 处理支付
  // 发送通知
  // 更新库存
  // 记录日志
  // ... 200 行代码
}

// 拆分后的函数
function processOrder(order) {
  validateOrder(order)
  const price = calculatePrice(order)
  const finalPrice = applyDiscount(price, order.discount)
  processPayment(finalPrice)
  sendNotification(order)
  updateInventory(order)
  logOrder(order)
}

代码度量工具

# 安装
npm install -D eslint-plugin-complexity

# 配置
// .eslintrc.js
module.exports = {
  plugins: ['complexity'],
  rules: {
    'complexity': ['error', 10],           // 圈复杂度上限
    'max-lines': ['error', 300],           // 文件行数上限
    'max-lines-per-function': ['error', 50], // 函数行数上限
    'max-params': ['error', 4],            // 参数数量上限
    'max-depth': ['error', 4],             // 嵌套深度上限
    'max-nested-callbacks': ['error', 3]   // 回调嵌套上限
  }
}

TypeScript 类型检查

// tsconfig.json
{
  "compilerOptions": {
    "strict": true,
    "noImplicitAny": true,
    "strictNullChecks": true,
    "strictFunctionTypes": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": true
  }
}

代码审查清单

功能正确性

  • 代码是否实现了需求
  • 边界条件是否处理
  • 错误处理是否完善
  • 是否有潜在的 bug

代码质量

  • 命名是否清晰有意义
  • 函数是否职责单一
  • 是否有重复代码
  • 是否有过度设计

性能

  • 是否有性能问题
  • 是否有不必要的计算
  • 是否有内存泄漏风险

安全

  • 是否有安全漏洞
  • 敏感数据是否处理
  • 输入是否验证

可维护性

  • 代码是否易于理解
  • 注释是否充分
  • 是否遵循团队规范

下一步

掌握代码质量后,你可以继续学习:


东巴文(db-w.cn)—— 让代码更优雅