
1. 为什么我们需要ESLint第一次接触ESLint是在三年前接手一个遗留项目时当时代码库里有各种风格的console.log、未使用的变量和混乱的缩进。团队成员对代码风格各执一词每次代码审查都变成风格争论。直到我们引入了ESLint这些问题才迎刃而解。ESLint本质上是一个静态代码分析工具它能在你编写代码时就发现问题而不是等到运行时才暴露错误。想象一下有个严格的代码审查员坐在你旁边实时指出每个潜在问题——这就是ESLint的作用。它特别适合JavaScript这种动态类型语言因为这类语言在编译阶段缺乏类型检查等安全机制。注意虽然ESLint最常用于JavaScript但它也支持TypeScript、JSX等语法通过插件可以扩展到几乎所有的现代前端框架。2. 基础配置与核心规则解析2.1 初始化ESLint配置安装ESLint只需要一个简单的npm命令npm install eslint --save-dev初始化配置文件时我推荐使用交互式命令行npx eslint --init这个向导会询问你一系列问题如何使用ESLint检查语法、发现问题、强制代码风格项目使用什么模块类型ES modules/CommonJS使用哪个框架React/Vue/None是否使用TypeScript代码运行环境Browser/Node如何定义代码风格使用流行风格指南/自定义对于大多数新项目我会选择使用流行风格指南中的Airbnb规范因为它覆盖了大多数最佳实践。生成的.eslintrc.js文件大概长这样module.exports { env: { browser: true, es2021: true, }, extends: [airbnb-base], parserOptions: { ecmaVersion: 12, sourceType: module, }, rules: { // 可以在这里覆盖或添加规则 }, };2.2 必须了解的十大核心规则no-unused-vars禁止未使用变量为什么重要未使用的变量浪费内存且可能隐藏逻辑错误配置示例no-unused-vars: [error, { args: none }]no-console限制console的使用生产环境应该移除所有console语句配置示例no-console: process.env.NODE_ENV production ? error : warneqeqeq强制使用和!避免JavaScript类型强制转换的陷阱配置示例eqeqeq: [error, always]indent缩进规则团队统一使用2空格还是4空格配置示例indent: [error, 2, { SwitchCase: 1 }]semi分号使用个人偏好我推荐始终使用分号配置示例semi: [error, always]quotes引号风格单引号vs双引号配置示例quotes: [error, single, { avoidEscape: true }]react-hooks/rules-of-hooksReact Hook规则对React项目至关重要需要额外安装eslint-plugin-react-hooksimport/order导入排序保持导入语句有序配置示例import/order: [error, { groups: [builtin, external, internal] }]max-len行长度限制避免过长的代码行配置示例max-len: [error, { code: 100, ignoreUrls: true }]no-param-reassign禁止参数重新赋值避免意外的参数修改配置示例no-param-reassign: [error, { props: true }]3. 高级配置技巧3.1 多环境配置策略在实际项目中我们通常需要针对不同环境配置不同的规则。我的做法是创建基础配置然后通过extends扩展.eslintrc.js # 基础配置 .eslintrc.dev.js # 开发环境特有配置 .eslintrc.prod.js # 生产环境特有配置 .eslintrc.test.js # 测试环境特有配置在package.json中配置对应的脚本{ scripts: { lint: eslint ., lint:prod: eslint . --config .eslintrc.prod.js, lint:fix: eslint . --fix } }3.2 自定义规则的编写当现有规则不能满足需求时可以编写自定义规则。比如我们曾需要一个规则来强制组件propTypes按字母顺序排列// rules/alphabetic-prop-types.js module.exports { meta: { type: suggestion, docs: { description: Ensure propTypes are declared in alphabetical order, }, }, create(context) { return { ClassProperty(node) { if (node.key.name propTypes node.value.type ObjectExpression) { const properties node.value.properties; let prevName ; for (const prop of properties) { const currentName prop.key.name || prop.key.value; if (currentName prevName) { context.report({ node: prop, message: PropTypes should be in alphabetical order, }); break; } prevName currentName; } } }, }; }, };然后在配置中引用rules: { local/alphabetic-prop-types: error }, plugins: [local], settings: { import/resolver: { node: { paths: [rules] // 自定义规则目录 } } }4. 集成与自动化4.1 与编辑器集成在VS Code中安装ESLint插件后添加以下配置实现保存时自动修复{ editor.codeActionsOnSave: { source.fixAll.eslint: true }, eslint.validate: [ javascript, javascriptreact, typescript, typescriptreact ] }4.2 预提交钩子配置使用husky和lint-staged可以在提交前自动检查修改的文件npm install husky lint-staged --save-devpackage.json配置{ husky: { hooks: { pre-commit: lint-staged } }, lint-staged: { *.{js,jsx,ts,tsx}: [ eslint --fix, git add ] } }4.3 CI/CD集成示例在GitHub Actions中的配置示例name: Lint on: [push, pull_request] jobs: eslint: runs-on: ubuntu-latest steps: - uses: actions/checkoutv2 - uses: actions/setup-nodev2 with: node-version: 14 - run: npm ci - run: npm run lint5. 常见问题与解决方案5.1 性能优化技巧当项目变大时ESLint可能会变慢。以下是我总结的优化方法增量检查只检查修改的文件eslint --cache --fix忽略大文件在配置中添加overrides: [ { files: [*.large.js], rules: { max-lines: [off] } } ]并行检查使用eslint-parallelnpx eslint-parallel **/*.js5.2 规则冲突处理当多个扩展配置中的规则冲突时优先级顺序是明确写在rules中的配置最后extends的配置先extends的配置常见的冲突解决方案使用eslint-config-prettier关闭与Prettier冲突的规则在rules中明确覆盖冲突规则创建中间配置来协调不同扩展5.3 团队规范制定建议在团队中推行ESLint时我建议从少量核心规则开始逐步增加对新规则进行充分讨论和公示设置过渡期允许暂时禁用某些规则定期回顾规则的有效性为特殊场景提供eslint-disable注释的使用指南一个实用的注释禁用示例// eslint-disable-next-line no-console -- 允许在错误处理中使用console console.error(Failed to load data);