ESLint配合VSCode 统一团队前端代码规范

2,086 阅读5分钟

本文已参与「新人创作礼」活动, 一起开启掘金创作之路。

前言

在项目团队开发时,经常遇到代码不规范的问题,比如代码没有format、format风格不一致、部分代码明显会导致Bug或其它问题等。这样的代码到了项目后期,会导致无法维护等严重问题。

如何统一开发团队内的代码风格、校验规则?如何去执行和监督?使用ESLint,配合VSCode,开发React项目完美体验。支持高亮不规范代码,保存文件自动格式化,Git commit自动检测等功能。

配置

ESLint 是一个开源的 JavaScript 代码检查工具,用来检查你的代码是否符合指定的规范。文档:中文 | 官方

首先安装ESLint npm包:npm install eslint -save-dev

然后可以通过eslint指令创建eslint config文件:eslint --init

如果提示eslint找不到,可以尝试运行./node_modules/.bin/eslint --init

然后根据提示按需求选择。

image.png

image.png

image.png

image.png

image.png

image.png

这里简单说明下这几个选项:

  1. How would you like to use ESLint?
    • 选项2相比选项1就是多了默认的推荐rules配置,选项3是在2基础上多了format相关rules
    • 这里以选项2为例,选项3会在下一篇文章讲到
  2. What type of modules does your project use?
    • 本文以esm(选项1)为例
  3. Which framework does your project use?
    • 本文以React为例
  4. Does your project use TypeScript?
    • 本文这里选No,没用TS
  5. Where does your code run?
    • 本文选了browser
  6. What format do you want your config file to be in?
    • config文件以什么格式创建,这里选了js格式
  7. Would you like to install them now with npm?
    • 由于上面选了React框架,需要额外安装eslint-plugin-react包,这里问是否安装。选Yes

指令会自动创建.eslintrc.js文件,如下:

module.exports = {
    "env": {
        "browser": true,
        "es2021": true
    },
    "extends": [
        "eslint:recommended",
        "plugin:react/recommended"
    ],
    "parserOptions": {
        "ecmaFeatures": {
            "jsx": true
        },
        "ecmaVersion": 13,
        "sourceType": "module"
    },
    "plugins": [
        "react"
    ],
    "rules": {
    }
};

更多config配置可以参考:中文 | 官方

默认配置里,自动添加了"eslint:recommended""plugin:react/recommended"两个官方推荐的rules集合,具体rules可以通过官方文档找到:

  • eslint官方:中文 | 官方 标记✅的包含在recommended
  • react官方:github | rules 标记☑️的包含在recommended

然后可以根据自己的需求,在config rules里添加其它rules,也可以覆盖recommended里的rules。可以给具体rules设置off error warn等level,具体配置这里就不说了,文档里已经很详细了。

指令

ESLint提供了一些指令,可以扫描单个或多个文件,也可以自动修复支持auto fixable的rules。

  • eslint test.js 扫描单个文件
  • eslint . 扫描根路径所有js文件
  • eslint test.js --quiet 只扫描error level rules
  • eslint test.jsx --fix 扫描文件,并自动修复支持auto fixable的rules
  • eslint . --ext .js,.jsx --fix 扫描根路径所有js和jsx文件,并自动修复

命令行里直接运行eslint指令可能提示找不到指令,可以用./node_modules/.bin/eslint执行,也可以把eslint install到global里 npm i eslint -g推荐把指令加到package.json scripts

"scripts": {
    "eslint": "eslint . --ext .js,.jsx",
    "eslint:error": "eslint . --ext .js,.jsx --quiet",
    "eslint:fix": "eslint . --ext .js,.jsx --fix"
},

image.png

更多指令参考官网:中文 | 官方


如果是React项目,运行之类时可能会抛下面的错误,需要在.eslintrc.js定义下react version。

image.png

// .eslintrc.js
"settings": {
    react: {
      version: "18.x"
    }
},

另外笔者这边项目里的webpack、babel js文件里(包括.eslintrc.js)用的是CommonJS,即 module.exports 这种形式,但是config里配置的是"sourceType": "module",导致了提示no-undef

image.png

一种方法可以定义globals全局变量,就不会被no-undef扫出来:

"globals": {
    module: "readonly",
    require: "readonly",
    process: "readonly",
    __dirname: "readonly",
},

另一种方法是添加.eslintignore文件,把部分文件过滤出去,不扫描:

// .eslintignore
node_modules
publish
*.md
.eslintrc.js
webpack.config.js

其它plugin

推荐下一些其它比较好用的plugin,可以方便解决一些特殊需求问题。

  1. eslint-plugin-react-hooks react hooks lint
  2. typescript-eslint typescript lint
  3. eslint-plugin-sonarjs sonar相关lint,推荐参考这篇:juejin.cn/post/720213…
  4. eslint-plugin-import import相关lint

VSCode

VSCode IDE可以安装 ESLint 扩展插件,支持自动读取.eslintrc.js配置,在Code里提示对应rules错误,浮动提示,autofix on save等。

image.png

设置Extension Settings,这里建议直接设置Workspace下的settings,设置后会在.vscode路径下生成settings.json文件,可以提交到git上统一开发团队内部规范。

image.png

// .vscode/settings.json
{
    "eslint.enable": true,
    "editor.codeActionsOnSave": {
        "source.fixAll.eslint": true // save文件时自动fix
    }
}

另外vscode settings里还有些其它好用的设置,比如类似 semi eol-last 这种rule(format相关的rules),支持autofix,然后敲代码时会经常提示红色的错误,很影响开发体验,总是不自觉的save,这种可以通过settings自定义对应rule的severity,即提示方式,比如下面例子设置为off,这样就不会有红色提示了,并且依然能支持scan和save autofix。

// .vscode/settings.json
{
    "eslint.enable": true,
    "editor.codeActionsOnSave": {
        "source.fixAll.eslint": true
    },
    "eslint.rules.customizations": [
        {
            "rule": "semi",
            "severity": "off"
        },
        {
            "rule": "eol-last",
            "severity": "off"
        }
    ]
}

Git commit

可以配合git钩子husky以及lint-staged,达到git提交时自动检测本次change的code,如果有规范错误,则commit会失败,并给出eslint具体错误。

npm install husky lint-staged -D

"husky": {
  "hooks": {
    "pre-commit": "lint-staged"
  }
},
"lint-staged": {
  "src/**": [
    "eslint --fix",
    "git add"
  ]
}

Format

ESLint也可以配置一些rules,达到format的效果。比如--init里自带的airbnb airbnb等几种默认代码风格,这部分将在下一篇文章中讲解

最后

以上就是ESLint的基本知识,还有很多知识有待发掘。通过给项目部署ESLint,可以有效提高代码质量,提高可读性,极大降低团队开发和维护成本。

Code

最后share下项目里经常用到的ESLint配置:

module.exports = {
  "env": {
    "browser": true,
    "es2021": true
  },
  "extends": [
    "eslint:recommended",
    "plugin:react/recommended"
  ],
  "parserOptions": {
    "ecmaFeatures": {
      "jsx": true
    },
    "ecmaVersion": 13,
    "sourceType": "module"
  },
  "plugins": [
    "react",
    "react-hooks",
  ],
  "settings": {
    react: {
      version: "18.x"
    }
  },
  "globals": {
    module: "readonly",
    require: "readonly",
    process: "readonly",
    __dirname: "readonly",
  },
  "rules": {
    // off some recommendeds
    'react/react-in-jsx-scope': "off",
    'react/prop-types': "off",

    // hooks
    "react-hooks/rules-of-hooks": "error",
    "react-hooks/exhaustive-deps": "warn",

    // enhances error
    "semi": "error",
    "eqeqeq": ["error", "always", { "null": "ignore" }],
    "comma-dangle": ["error", "only-multiline"],
    "eol-last": "error",
    "radix": "error",
    "no-const-assign": "error",
    "no-eval": "error",
    "no-implied-eval": "error",
    "no-use-before-define": ["error", { "functions": false, "classes": false, "variables": false }],
    "no-self-compare": "error",
    "guard-for-in": "error",
    "default-param-last": "error",
    "array-callback-return": ["error", { "allowImplicit": false, "checkForEach": false }],
    "no-unused-expressions": ["error", { "allowShortCircuit": true, "allowTernary": true, "allowTaggedTemplates": true }],
    "no-shadow": "error",
    "no-duplicate-imports": "error",

    // enhances warn
    "no-unused-vars": ["warn", {
      "args": "none",
      "caughtErrors": "none",
      "ignoreRestSiblings": true,
      "vars": "all",
    }],
  }
};