手把手带你基于ESLint 9+Husky+Prettier+Commitlint+Lint-staged配置前端开发规范
在前端项目开发中,代码规范是保证代码质量和团队协作效率的基础。一个完善的代码规范体系不仅能统一团队成员的编码风格,还能在代码提交前自动检查问题,减少代码review的成本。
本文将手把手教你搭建一套完整的前端开发规范体系,基于ESLint 9新配置系统,配合Husky、Prettier、Commitlint、Lint-staged等工具,实现代码提交前的自动检查和格式化。
# 一、项目初始化与依赖安装
# 创建Next.js 16项目
npx create-next-app@latest my-app --typescript --tailwind --eslint
cd my-app
@前端进阶之旅: 代码已经复制到剪贴板
# 安装ESLint 9相关依赖
npm install eslint@9 @eslint/js@9 --save-dev
npm install typescript-eslint@8 --save-dev
npm install eslint-config-next@16 --save-dev
npm install eslint-plugin-simple-import-sort@12 eslint-plugin-unused-imports@4 --save-dev
npm install @eslint/compat@1 --save-dev
@前端进阶之旅: 代码已经复制到剪贴板
# 安装Prettier相关依赖
npm install prettier@3 prettier-plugin-tailwindcss@0.7 --save-dev
npm install eslint-config-prettier@10 --save-dev
@前端进阶之旅: 代码已经复制到剪贴板
# 安装Git钩子相关依赖
npm install husky@9 lint-staged@16 --save-dev
npm install @commitlint/cli@17 @commitlint/config-conventional@17 --save-dev
@前端进阶之旅: 代码已经复制到剪贴板
# 完整依赖清单
{
"devDependencies": {
"@commitlint/cli": "^17.7.2",
"@commitlint/config-conventional": "^17.7.0",
"@eslint/compat": "^1.4.1",
"@eslint/eslintrc": "^3",
"eslint": "^9.39.0",
"eslint-config-next": "^16.0.1",
"eslint-config-prettier": "^10.1.8",
"eslint-plugin-prettier": "^5.5.4",
"eslint-plugin-react-hooks": "^7.0.1",
"eslint-plugin-simple-import-sort": "^12.1.1",
"eslint-plugin-unused-imports": "^4.3.0",
"husky": "^9.1.7",
"lint-staged": "^16.2.6",
"prettier": "^3.6.2",
"prettier-plugin-tailwindcss": "^0.7.1",
"typescript": "^5.9.3"
}
}
@前端进阶之旅: 代码已经复制到剪贴板
# 二、ESLint 9扁平化配置
ESLint 9采用了全新的Flat Config(扁平化配置)系统,配置文件格式从.eslintrc.json变为eslint.config.mjs。
# 创建ESLint配置文件
// eslint.config.mjs
import { defineConfig, globalIgnores } from 'eslint/config'
import nextVitals from 'eslint-config-next/core-web-vitals'
import nextTs from 'eslint-config-next/typescript'
import tseslint from 'typescript-eslint'
import simpleImportSort from 'eslint-plugin-simple-import-sort'
import unusedImports from 'eslint-plugin-unused-imports'
import { fixupPluginRules } from '@eslint/compat'
// ESLint 9扁平化配置
const eslintConfig = defineConfig([
...nextVitals,
...nextTs,
tseslint.configs.recommendedTypeChecked,
{
files: ['src/**/*.{js,jsx,ts,tsx}'],
plugins: {
'simple-import-sort': fixupPluginRules(simpleImportSort),
'unused-imports': fixupPluginRules(unusedImports)
},
extends: [],
languageOptions: {
parserOptions: {
projectService: true
},
globals: {
JSX: true
}
},
rules: {
// 关闭部分严格规则,适应项目需求
semi: 'off',
'@typescript-eslint/explicit-member-accessibility': 'off',
'trailing-comma': 'off',
'simple-import-sort/imports': 'warn',
'simple-import-sort/exports': 'warn',
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/ban-ts-comment': 'off',
'@typescript-eslint/no-var-requires': 'off',
'@typescript-eslint/no-unused-vars': 'off',
'no-unused-vars': 'off',
'react-hooks/exhaustive-deps': 'off',
'react/display-name': 'off',
'import/no-anonymous-default-export': 'off',
'react-hooks/rules-of-hooks': 'off',
'unused-imports/no-unused-imports': 'error',
'react/no-children-prop': 'off',
'@next/next/no-img-element': 'off',
'jsx-a11y/alt-text': 'off',
'@typescript-eslint/no-unused-expressions': 'off',
'@typescript-eslint/no-empty-object-type': 'off',
'@typescript-eslint/no-require-imports': 'off',
'prefer-const': 'off',
'@typescript-eslint/ban-types': 'off',
'@typescript-eslint/no-unsafe-member-access': 'off',
'@typescript-eslint/no-unsafe-argument': 'off',
'@typescript-eslint/no-unsafe-assignment': 'off',
'@typescript-eslint/no-unsafe-call': 'off',
'@typescript-eslint/no-unsafe-return': 'off',
'@typescript-eslint/prefer-promise-reject-errors': 'off',
'@typescript-eslint/no-misused-promises': 'off',
'@typescript-eslint/require-await': 'off',
'@typescript-eslint/restrict-template-expressions': 'off',
'@typescript-eslint/no-floating-promises': 'off',
'@typescript-eslint/only-throw-error': 'off',
'@typescript-eslint/await-thenable': 'off',
'react-hooks/set-state-in-effect': 'off',
'react-hooks/purity': 'off',
'react-hooks/immutability': 'off',
'typescript-eslint/unbound-method': 'off',
'react-hooks/refs': 'off',
'react-hooks/preserve-manual-memoization': 'off',
'@typescript-eslint/no-base-to-string': 'off',
// 唯一开启的强制规则:图片必须有alt属性
'jsx-a11y/alt-text': 'error'
}
},
// 忽略文件配置
globalIgnores([
'.next/**',
'out/**',
'build/**',
'next-env.d.ts',
'eslint.config.mjs',
'node_modules/**',
'**/*.json',
'**/.vscode',
'.husky/**'
])
])
export default eslintConfig
@前端进阶之旅: 代码已经复制到剪贴板
# package.json中添加ESLint脚本
{
"scripts": {
"eslint": "npx eslint --fix src"
}
}
@前端进阶之旅: 代码已经复制到剪贴板
# 三、Prettier代码格式化配置
Prettier负责代码格式统一,与ESLint分工明确:ESLint检查代码质量,Prettier负责代码风格。
# 创建Prettier配置文件
# 创建Prettier忽略文件
# .prettierignore
node_modules
.next
out
build
dist
coverage
*.lock
package-lock.json
yarn.lock
pnpm-lock.yaml
@前端进阶之旅: 代码已经复制到剪贴板
# package.json中添加Prettier脚本
{
"scripts": {
"prettier": "prettier --write ./src"
}
}
@前端进阶之旅: 代码已经复制到剪贴板
# 四、EditorConfig编辑器配置
EditorConfig帮助统一编辑器的行为,包括缩进、换行等基础设置。
# 五、VSCode自动校验配置
在VSCode中配置保存时自动格式化代码和修复ESLint问题,大幅提升开发体验。
# 创建VSCode工作区配置
# 配置说明
# 推荐的VSCode扩展
