0%

Husky + ESLint + Prettier——代码规范化完整配置

代码规范统一,husky+eslint+prettier+lint-staged 的组合确实是前端项目的标准配置,能有效保证代码质量和团队协作效率。

代码规范工具链概述

  在现代前端开发中,代码质量是项目成功的关键因素之一。一个完整的代码规范工具链包括静态代码检查、代码格式化、Git 钩子管理和增量检查等功能。husky、eslint、prettier 和 lint-staged 共同构成了这样一个生态系统,确保代码在提交前符合预定的规范。

  这四个工具各有分工:

  1. Husky: 管理 Git 钩子,实现提交前的自动化检查
  2. ESLint: 静态代码分析,检测语法错误和代码质量问题
  3. Prettier: 代码格式化工具,统一代码风格
  4. lint-staged: 针对暂存区文件的检查工具,提高检查效率

工具链工作流程

1
2
3
4
5
6
7
8
9
10
11
graph TD
A[编写代码] --> B[Git Add 暂存文件]
B --> C[Git Commit 提交]
C --> D[Husky 触发 pre-commit 钩子]
D --> E[lint-staged 选择暂存文件]
E --> F[并行执行 ESLint & Prettier]
F --> G{检查通过?}
G -->|否| H[修正错误并重新提交]
G -->|是| I[成功提交到仓库]
H --> C
I --> J[代码质量保障]

ESLint 详解

ESLint 基础配置

1
2
3
4
# 安装 ESLint
npm install --save-dev eslint

# 初始化配置 npx eslint --init

基础配置文件 (.eslintrc.JS)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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
module.exports = {
// 指定 ECMAScript 版本和支持的全局变量 env: {
browser: true,
es2021: true,
Node: true,
jest: true
},

// 解析器配置 parser: '@babel/eslint-parser',
parserOptions: {
ecmaVersion: 2021,
sourceType: 'module',
requireConfigFile: false,
babelOptions: {
presets: ['@babel/preset-React']
}
},

// 继承基础规则 extends: [
'eslint:recommended',
'plugin:React/recommended',
'plugin:import/errors',
'plugin:import/warnings'
],

// 插件 plugins: [
'React',
'import'
],

// 规则配置 rules: {
// 错误级别的规则
'no-console': 'error',
'no-debugger': 'error',

// 警告级别的规则
'no-unused-vars': 'warn',
'no-undef': 'error',

// 代码风格规则
'prefer-const': 'error',
'no-var': 'error',
'semi': ['error', 'always'],
'quotes': ['error', 'single'],

// React 相关规则
'React/React-in-jsx-scope': 'off',
'React/prop-types': 'off'
},

// 覆盖特定文件的配置 overrides: [
{
files: ['*.test.JS', '*.spec.JS'],
env: {
jest: true
},
rules: {
'no-console': 'off'
}
}
]
};

高级 ESLint 配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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
107
108
// .eslintrc.JS - 高级配置示例 module.exports = {
root: true,

env: {
browser: true,
es2021: true,
Node: true
},

parser: '@Typescript-eslint/parser',
parserOptions: {
ecmaVersion: 2021,
sourceType: 'module',
project: './tsconfig.Json' // Typescript 项目配置
},

extends: [
'eslint:recommended',
'@Typescript-eslint/recommended',
'plugin:React/recommended',
'plugin:jsx-a11y/recommended',
'plugin:import/recommended',
'plugin:import/Typescript',
'prettier' // 与 Prettier 集成
],

plugins: [
'@Typescript-eslint',
'React',
'jsx-a11y',
'import',
'unused-imports'
],

settings: {
React: {
version: 'detect'
},
'import/resolver': {
Typescript: {
project: './tsconfig.Json'
}
}
},

rules: {
// Typescript 规则
'@Typescript-eslint/no-unused-vars': 'error',
'@Typescript-eslint/explicit-function-return-type': 'off',
'@Typescript-eslint/explicit-module-boundary-types': 'off',
'@Typescript-eslint/no-explicit-any': 'warn',

// React 规则
'React/jsx-uses-React': 'off',
'React/React-in-jsx-scope': 'off',
'React/prop-types': 'off',
'React/display-name': 'off',

// Import 规则
'import/order': [
'error',
{
groups: [
'builtin', // Node.JS 内置模块
'external', // 第三方模块
'internal', // 内部模块
'parent', // 父目录
'sibling', // 同级目录
'index' // 当前目录
],
'newlines-between': 'always',
alphabetize: {
order: 'asc',
caseInsensitive: true
}
}
],

// 未使用导入检测
'unused-imports/no-unused-imports': 'error',
'unused-imports/no-unused-vars': [
'warn',
{
vars: 'all',
varsIgnorePattern: '^_',
args: 'after-used',
argsIgnorePattern: '^_'
}
],

// 其他规则
'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'warn',
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'warn'
},

overrides: [
{
files: ['*.test.JS', '*.test.TS', '*.test.jsx', '*.test.tsx'],
env: {
jest: true
},
rules: {
'no-console': 'off',
'no-debugger': 'off'
}
}
]
};

Prettier 详解

Prettier 基础配置

1
2
# 安装 Prettier
npm install --save-dev prettier

Prettier 配置文件 (.prettierrc)

1
2
3
4
5
6
7
8
9
10
11
{
"semi": true,
"trailingComma": "es5",
"singleQuote": true,
"printWidth": 80,
"tabWidth": 2,
"useTabs": false,
"bracketSpacing": true,
"arrowParens": "avoid",
"endOfLine": "lf"
}

Prettier 高级配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
// .prettierrc.JS
module.exports = {
semi: true,
trailingComma: 'es5',
singleQuote: true,
printWidth: 100,
tabWidth: 2,
useTabs: false,
bracketSpacing: true,
arrowParens: 'avoid',
proseWrap: 'always',
endOfLine: 'lf',
jsxSingleQuote: false,
quoteProps: 'consistent',
rangeStart: 0,
rangeEnd: Infinity,
embeddedLanguageFormatting: 'auto',
htmlWhitespaceSensitivity: 'Css',
vueIndentScriptAndStyle: false,

// 忽略特定文件的配置 overrides: [
{
files: '*.Json',
options: {
printWidth: 200
}
},
{
files: '*.{yaml,yml}',
options: {
tabWidth: 2,
printWidth: 80
}
},
{
files: '*.md',
options: {
printWidth: 80,
proseWrap: 'preserve'
}
}
]
};

Prettier 与 ESLint 集成

1
# 安装集成插件 npm install --save-dev eslint-config-prettier eslint-plugin-prettier
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// .eslintrc.JS - 与 Prettier 集成 module.exports = {
extends: [
'eslint:recommended',
'@Typescript-eslint/recommended',
'plugin:React/recommended',
'prettier' // 关闭与 Prettier 冲突的规则
],

plugins: [
'React',
'prettier' // Prettier 插件
],

rules: {
'prettier/prettier': 'error' // 将 Prettier 的格式化问题作为 ESLint 错误
}
};

lint-staged 详解

lint-staged 安装和配置

1
2
# 安装 lint-staged
npm install --save-dev lint-staged

lint-staged 配置 (.lintstagedrc)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
{
"*.{JS,jsx,TS,tsx}": [
"eslint --fix",
"prettier --write",
"git add"
],
"*.{Json,md,yml,yaml}": [
"prettier --write",
"git add"
],
"*.{Css,scss,less}": [
"prettier --write",
"stylelint --fix",
"git add"
],
"*.{JS,jsx,TS,tsx,Json,md,Css,scss,less}": [
"npm run test:staged"
]
}

高级 lint-staged 配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
// lint-staged.config.JS
module.exports = {
// Javascript/Typescript 文件
'*.{JS,jsx,TS,tsx}': [
(filenames) => {
// 只对修改的文件运行 ESLint 修复 return [`eslint --fix ${filenames.join(' ')}`, `git add ${filenames.join(' ')}`];
},
(filenames) => {
// 只对修改的文件运行 Prettier
return [`prettier --write ${filenames.join(' ')}`, `git add ${filenames.join(' ')}`];
}
],

// Json 文件
'*.Json': (filenames) => [
`prettier --write ${filenames.join(' ')}`,
`git add ${filenames.join(' ')}`
],

// Markdown 文件
'*.md': (filenames) => [
`remark ${filenames.join(' ')} -qfo`,
`prettier --write ${filenames.join(' ')}`,
`git add ${filenames.join(' ')}`
],

// 样式文件
'*.{Css,scss,less}': [
(filenames) => [
`stylelint --fix ${filenames.join(' ')}`,
`prettier --write ${filenames.join(' ')}`,
`git add ${filenames.join(' ')}`
]
],

// 验证提交消息
'COMMIT_EDITMSG': 'commitlint -E HUSKY_GIT_PARAMS'
};

Husky 详解

Husky 安装和配置

1
2
3
4
5
6
7
8
9
# 安装 Husky
npm install --save-dev husky

# 启用 Git hooks
npx husky install

# 添加 pre-commit 钩子 npx husky add .husky/pre-commit "npx lint-staged"

# 添加 commit-msg 钩子 npx husky add .husky/commit-msg 'npx --no-install commitlint --edit "$1"'

完整的 Husky 配置

1
2
3
4
5
6
7
8
9
10
11
# .husky/pre-commit
#!/usr/bin/env sh
. "$(dirname "$0")/_/husky.sh"

# 检查是否安装了 lint-staged
if [ -x "$(command -v npx)" ]; then
npx lint-staged
else
echo "Error: npx is not available"
exit 1
fi
1
2
3
4
5
# .husky/commit-msg
#!/usr/bin/env sh
. "$(dirname "$0")/_/husky.sh"

# 验证提交消息格式 npx --no-install commitlint --edit $1
1
2
3
4
5
6
# .husky/pre-push
#!/usr/bin/env sh
. "$(dirname "$0")/_/husky.sh"

# 推送前运行完整测试套件 npm run test
npm run build

实际应用案例

案例1: React + Typescript 项目配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
// package.Json
{
"scripts": {
"lint": "eslint src --ext .TS,.tsx",
"lint:fix": "eslint src --ext .TS,.tsx --fix",
"format": "prettier --write \"src/**/*.{JS,jsx,TS,tsx,Json,md}\"",
"format:check": "prettier --check \"src/**/*.{JS,jsx,TS,tsx,Json,md}\"",
"prepare": "husky install",
"pre-commit": "lint-staged",
"type-check": "tsc --noEmit"
},
"lint-staged": {
"*.{TS,tsx}": [
"eslint --fix",
"prettier --write",
"git add"
],
"*.{JS,jsx,Json,md}": [
"prettier --write",
"git add"
]
},
"devDependencies": {
"husky": "^8.0.0",
"lint-staged": "^13.0.0",
"eslint": "^8.0.0",
"prettier": "^2.0.0",
"@Typescript-eslint/parser": "^5.0.0",
"@Typescript-eslint/eslint-plugin": "^5.0.0",
"eslint-plugin-React": "^7.0.0",
"eslint-config-prettier": "^8.0.0",
"eslint-plugin-prettier": "^4.0.0"
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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
// .eslintrc.JS - React + Typescript 项目 module.exports = {
root: true,
env: {
browser: true,
es2021: true,
Node: true
},
extends: [
'eslint:recommended',
'@Typescript-eslint/recommended',
'plugin:React/recommended',
'plugin:React-hooks/recommended',
'plugin:jsx-a11y/recommended',
'prettier'
],
parser: '@Typescript-eslint/parser',
parserOptions: {
ecmaFeatures: {
jsx: true
},
ecmaVersion: 12,
sourceType: 'module',
project: './tsconfig.Json'
},
plugins: [
'React',
'@Typescript-eslint',
'React-hooks',
'jsx-a11y',
'prettier'
],
settings: {
React: {
version: 'detect'
}
},
rules: {
'prettier/prettier': 'error',
'React/React-in-jsx-scope': 'off',
'React/prop-types': 'off',
'@Typescript-eslint/no-unused-vars': 'error',
'@Typescript-eslint/explicit-function-return-type': 'off',
'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'warn',
'React-hooks/rules-of-hooks': 'error',
'React-hooks/exhaustive-deps': 'warn'
}
};

案例2: Node.JS 服务端项目配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
// package.Json - Node.JS 项目
{
"scripts": {
"lint": "eslint src test --ext .JS,.TS",
"lint:fix": "eslint src test --ext .JS,.TS --fix",
"format": "prettier --write \"src/**/*.{JS,TS,Json,md}\" \"test/**/*.{JS,TS,Json,md}\"",
"pre-commit": "lint-staged",
"test": "jest",
"test:staged": "jest --bail --passWithNoTests --findRelatedTests"
},
"lint-staged": {
"*.{JS,TS}": [
"eslint --fix",
"prettier --write",
"jest --bail --passWithNoTests --findRelatedTests",
"git add"
],
"*.{Json,md}": [
"prettier --write",
"git add"
]
},
"devDependencies": {
"husky": "^8.0.0",
"lint-staged": "^13.0.0",
"eslint": "^8.0.0",
"prettier": "^2.0.0",
"@Typescript-eslint/parser": "^5.0.0",
"@Typescript-eslint/eslint-plugin": "^5.0.0",
"eslint-plugin-Node": "^11.0.0",
"eslint-config-prettier": "^8.0.0",
"eslint-plugin-prettier": "^4.0.0",
"jest": "^29.0.0"
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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
// .eslintrc.JS - Node.JS 服务端项目 module.exports = {
env: {
Node: true,
es2021: true,
jest: true
},
extends: [
'eslint:recommended',
'@Typescript-eslint/recommended',
'plugin:Node/recommended',
'prettier'
],
parser: '@Typescript-eslint/parser',
parserOptions: {
ecmaVersion: 12,
sourceType: 'module',
project: './tsconfig.Json'
},
plugins: [
'@Typescript-eslint',
'Node',
'prettier'
],
rules: {
'prettier/prettier': 'error',
'Node/no-extraneous-imports': 'off',
'Node/no-missing-import': 'off',
'Node/no-unsupported-features/es-syntax': 'off',
'Node/no-unpublished-import': 'off',
'@Typescript-eslint/no-unused-vars': 'error',
'no-console': 'warn',
'Node/shebang': 'off'
},
overrides: [
{
files: ['test/**/*', '__tests__/**/*'],
env: {
jest: true
},
rules: {
'Node/no-unpublished-require': 'off',
'Node/no-missing-require': 'off'
}
}
]
};

案例3: 前端 + 后端一体化项目

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
// monorepo 项目结构
// .
// ├── frontend/
// │ ├── package.Json
// │ ├── .eslintrc.JS
// │ └── .prettierrc
// ├── backend/
// │ ├── package.Json
// │ ├── .eslintrc.JS
// │ └── .prettierrc
// ├── .husky/
// ├── .lintstagedrc
// ├── package.Json (root)
// └── pnpm-workspace.yaml

// 根目录 package.Json
{
"scripts": {
"prepare": "husky install",
"lint": "pnpm --recursive lint",
"format": "pnpm --recursive format",
"test": "pnpm --recursive test"
},
"lint-staged": {
"frontend/**/*.{JS,jsx,TS,tsx}": [
"cd frontend && npx eslint --fix",
"cd frontend && npx prettier --write",
"git add"
],
"backend/**/*.{JS,TS}": [
"cd backend && npx eslint --fix",
"cd backend && npx prettier --write",
"git add"
],
"**/*.{Json,md}": [
"npx prettier --write",
"git add"
]
}
}

工作流程优化

1. 性能优化配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
// lint-staged.config.JS - 性能优化版本 const { ESLint } = require('eslint');
const prettier = require('prettier');

// 创建 ESLint 实例,避免重复初始化 const eslint = new ESLint({
fix: true,
useEslintrc: true
});

module.exports = {
'*.{JS,jsx,TS,tsx}': async (filenames) => {
// 并行执行 ESLint 和 Prettier
await Promise.all([
// 运行 ESLint 修复 eslint.lintFiles(filenames).then(() => {
return eslint.outputFixes(filenames.map(file => ({ filePath: file })));
}),

// 运行 Prettier 格式化 Promise.all(filenames.map(async (file) => {
const config = await prettier.resolveConfig(file);
const fileInfo = await prettier.getFileInfo(file);

if (fileInfo.ignored) return;

const code = await require('fs').promises.readFile(file, 'utf8');
const formatted = prettier.format(code, { ...config, filepath: file });

if (formatted !== code) {
await require('fs').promises.writeFile(file, formatted, 'utf8');
}
}))
]);

return filenames;
}
};

2. 错误处理和日志

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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
// scripts/lint-logger.JS
const { execSync } = require('child_process');
const fs = require('fs');

function runLintWithLogging() {
const startTime = Date.now();
console.log('🔍 开始代码检查...');

try {
// 检查是否有暂存文件 const stagedFiles = execSync('git diff --cached --name-only --diff-filter=ACMR')
.toString()
.trim()
.split('\n')
.filter(Boolean);

if (stagedFiles.length === 0) {
console.log('✅ 没有暂存的文件,跳过检查');
return 0;
}

console.log(`📝 检查文件: ${stagedFiles.join(', ')}`);

// 运行 ESLint
console.log('🔍 运行 ESLint...');
const eslintResult = execSync('npx eslint --fix ' + stagedFiles.join(' '), {
stdio: 'pipe',
encoding: 'utf-8'
});

// 运行 Prettier
console.log('✨ 运行 Prettier...');
execSync('npx prettier --write ' + stagedFiles.join(' '), {
stdio: 'pipe'
});

const duration = Date.now() - startTime;
console.log(`✅ 代码检查完成,耗时 ${duration}ms`);

// 重新添加修复后的文件 execSync('git add ' + stagedFiles.join(' '));

return 0;

} catch (error) {
const duration = Date.now() - startTime;
console.error(`❌ 代码检查失败,耗时 ${duration}ms`);
console.error(error.stdout || error.stderr || error.message);

console.log('\n💡 解决建议:');
console.log('- 修复显示的错误后重试');
console.log('- 使用 npm run lint:fix 手动修复');
console.log('- 检查配置文件是否有误');

return 1;
}
}

const exitCode = runLintWithLogging();
process.exit(exitCode);

3. 条件检查配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// conditional-lint-staged.config.JS
module.exports = {
'*.{JS,jsx,TS,tsx}': (filenames) => {
// 根据文件类型选择不同的检查规则 const jsFiles = filenames.filter(file => file.endsWith('.JS'));
const tsFiles = filenames.filter(file => file.endsWith('.TS'));
const jsxFiles = filenames.filter(file => file.endsWith('.jsx'));
const tsxFiles = filenames.filter(file => file.endsWith('.tsx'));

const commands = [];

if (jsFiles.length > 0) {
commands.push(`eslint --fix ${jsFiles.join(' ')}`);
}

if (tsFiles.length > 0 || tsxFiles.length > 0) {
commands.push(`eslint --fix ${[...tsFiles, ...tsxFiles].join(' ')}`);
}

if (jsxFiles.length > 0 || tsxFiles.length > 0) {
commands.push(`eslint --fix ${[...jsxFiles, ...tsxFiles].join(' ')}`);
}

commands.push(`prettier --write ${filenames.join(' ')}`);
commands.push(`git add ${filenames.join(' ')}`);

return commands;
}
};

常见问题和解决方案

1. 性能问题

1
2
3
4
5
6
7
8
9
// 优化大项目性能
// 使用并行处理和缓存 const os = require('os');
const { ESLint } = require('eslint');

const cpuCount = os.cpus().length;
const eslint = new ESLint({
fix: true,
threads: cpuCount > 1 ? cpuCount : false, // 多线程处理 cache: true, // 启用缓存 cacheLocation: './node_modules/.cache/.eslintcache'
});

2. 配置冲突解决

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 解决 ESLint 和 Prettier 冲突
// .eslintrc.JS
module.exports = {
extends: [
'eslint:recommended',
'plugin:React/recommended',
'prettier' // 放在最后关闭冲突规则
],
plugins: ['prettier'],
rules: {
'prettier/prettier': 'error', // 将 Prettier 格式问题作为错误
// 如有特殊需求,可以重新开启某些 ESLint 规则
'comma-dangle': ['error', 'always-multiline']
}
};

3. CI/CD 集成

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# .github/workflows/lint.yml
name: Code Quality

on:
push:
branches: [main, develop]
pull_request:
branches: [main]

jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0 # 获取所有历史用于 lint-staged

- name: Setup Node.JS
uses: actions/setup-Node@v3
with:
Node-version: '18'
cache: 'npm'

- name: Install dependencies
run: npm ci

- name: Run ESLint
run: npx eslint src --ext .JS,.TS,.jsx,.tsx

- name: Run Prettier check
run: npx prettier --check "src/**/*.{JS,TS,jsx,tsx,Json,md}"

- name: Run type checking
run: npx tsc --noEmit

最佳实践

1. 配置文件管理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 项目结构建议 project/
├── .github/
│ └── workflows/
│ └── lint.yml
├── .husky/
│ ├── pre-commit
│ └── commit-msg
├── .vscode/
│ └── settings.Json
├── .eslintrc.JS
├── .prettierrc
├── .lintstagedrc
├── package.Json
└── README.md

2. IDE 集成配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// .vscode/settings.Json
{
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
},
"eslint.validate": [
"Javascript",
"javascriptreact",
"Typescript",
"typescriptreact"
],
"prettier.configPath": "./.prettierrc",
"eslint.workingDirectories": ["./src"]
}

3. 团队协作规范

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 代码规范指南

## 安装依赖 npm install

## 开发前准备
确保安装了必要的 IDE 插件:
- ESLint
- Prettier

## 提交代码
正常提交即可,钩子会自动检查和修复格式

## 本地检查
- `npm run lint` - 检查代码规范
- `npm run format` - 格式化所有文件
- `npm run lint:fix` - 自动修复可修复的问题

总结

  • husky+eslint+prettier+lint-staged 构成了完整的代码质量保障体系
  • 合理配置可以大大提高开发效率和代码质量
  • 性能优化和错误处理很重要
  • CI/CD 集成确保代码质量的一致性
  • 团队协作需要统一的规范和工具
  • 定期更新配置保持最佳实践

这套工具链确实让团队开发规范了许多,代码审查的负担减轻不少。现在新同事加入也能快速适应项目的代码风格,这就是工程化的价值所在。

扩展阅读

  • ESLint Official Documentation
  • Prettier Documentation
  • Husky Guide
  • lint-staged Documentation
  • Javascript Code Quality Guide

参考资料

  • ESLint: https://eslint.org/
  • Prettier: https://prettier.io/
  • Husky: https://github.com/typicode/husky
  • lint-staged: https://github.com/okonet/lint-staged
  • Frontend Guidelines: https://github.com/bendc/frontend-guidelines
bulb