高质量的代码是项目成功的关键。通过代码规范、静态检查和自动化工具,可以显著提升代码的可维护性和可靠性。
// 变量命名 - 小驼峰
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 是 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 是代码格式化工具,自动统一代码风格。
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}\""
}
}
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 在提交前自动检查代码。
# 安装
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"]
}
}
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] // 回调嵌套上限
}
}
// tsconfig.json
{
"compilerOptions": {
"strict": true,
"noImplicitAny": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true
}
}
掌握代码质量后,你可以继续学习:
东巴文(db-w.cn)—— 让代码更优雅