Eslint使用入门指南

11,099 阅读17分钟

官方文档【英文版】 英文文档

官方文档【中文版】 中文文档

原文地址【原地址】 博客地址

Eslint是用来干嘛的

ESLint最初是由Nicholas C. Zakas 于2013年6月创建的开源项目。它的目标是提供一个插件化的javascript代码检测工具。

为什么要使用Eslint

ESLint 是一个开源的 JavaScript 代码检查工具,。代码检查是一种静态的分析,常用于寻找有问题的模式或者代码,并且不依赖于具体的编码风格。对大多数编程语言来说都会有代码检查,一般来说编译程序会内置检查工具。

但是由于javascript的动态弱类型语言特性,导致在开发中如果不加以约束会容易出错,也正是因为这种特性导致当程序出现错误的时候,我们需要花费更多的时间在执行的过程中不断去调试,Eslint的出现就是为了让开发人员可以在开发的过程中就发现错误而非在执行过程中。

Eslint保持其插件的特性,让开发人员自定义定制属于自己的规则,也可以去遵循一些大的社区或者团队的规范直接继承下来用于使用,其所有规则都是可插入的,同时为了方便使用,也对其内置了一些规则。

安装

  • 局部安装:npm install eslint --save-dev
  • 全局安装:npm install eslint -g
  • 版本要求 nodejs >= 6.14、 npm 3+

使用

首先我们要使用eslint我们需要配置一份eslint的专属配置文件放置在项目的根目录上,可以用个cli命令行工具直接生成,如果是全局安装可以直接eslint --int、如果是本地安装则./node_modules/.bin/eslint --init两个操作没有区别接下来会生成一份基础的Eslint配置文件,你可以选择JSJSONYAML等格式、同时在其中可以选择一些你需要的规则,如果你是初次上次,那么我建议你全部回车,在选择框架的地方建议首次选择none,暂时我们先不去考虑如何集成框架,接下来就可以生成下图的一份配置,全部标上注释更方便你的理解。

module.exports = {
    "env": { // 环境
        "browser": true,
        "es2021": true
    },
    "extends": "eslint:recommended", // 可共享配置的名称、eslint:recommended 或 eslint:all,表示默认开启一些内置的规则,包含的,在 https://eslint.bootcss.com/docs/rules/ 中可以查看内置规则
    "parserOptions": {
        "ecmaVersion": "latest", // 指定你想要使用的 ECMAScript 版本
        "sourceType": "module" //"script" (默认) 或 "module"(如果你的代码是 ECMAScript 模块)
    },
    "rules": { // 配置规则的地方 这里就是我们所需要配置的规则
    }
}
​

规则配置

基础配置规则注意事项
  • "off"0 - 关闭规则

  • "warn"1 - 开启规则,使用警告级别的错误:warn (不会导致程序退出)

  • "error"2 - 开启规则,使用错误级别的错误:error (当被触发的时候,程序会退出)

  • 正常的配置通常是键值对的形式,那么这一类的配置是没有属性的只需要开启关闭即可类似于

    "no-cond-assign": 2,
    "no-console": 1,
    

    当然部分属性有自己的属性,在控制开关的同时还需要配置属性,例如

    {
        rules: {
            'quotes': ['error', 'single'],  // 如果不是单引号,则报错
            'one-var': ['error', {
                'var': 'always',  // 每个函数作用域中,只允许 1 个 var 声明
                'let': 'never',   // 每个块作用域中,允许多个 let 声明
                'const': 'never', // 每个块作用域中,允许多个 const 声明
            }]
        }
    }
    
  • Eslint的配置格式可以包含以下五种

    • JavaScript - 使用 .eslintrc.js 然后输出一个配置对象。
    • YAML - 使用 .eslintrc.yaml 或 .eslintrc.yml 去定义配置的结构
    • JSON - 使用 .eslintrc.json 去定义配置的结构,ESLint 的 JSON 文件允许 JavaScript 风格的注释。
    • (弃用) - 使用 .eslintrc,可以使 JSON 也可以是 YAML。
    • package.json - 在 package.json 里创建一个 eslintConfig属性,在那里定义配置。
  • 当出现多份配置的时候则会按以下优先级进行排列

    1 .eslintrc.js
    2 .eslintrc.yaml
    3 .eslintrc.yml
    4 .eslintrc.json
    5 .eslintrc
    6  package.json
    
常用配置规则列表【更多规则参官方文档
配置属性配置说明推荐配置
comma-dangle是否允许对象中出现结尾逗号["error", "never"]
no-cond-assign条件语句的条件中不允许出现赋值运算符2
no-console不允许出现console语句2
no-constant-condition条件语句的条件中不允许出现恒定不变的量2
no-control-regex正则表达式中不允许出现控制字符2
no-debugger不允许出现debugger语句2
no-dupe-args函数定义的时候不允许出现重复的参数2
no-dupe-keys对象中不允许出现重复的键2
no-duplicate-caseswitch语句中不允许出现重复的case标签2
no-empty不允许出现空的代码块2
no-empty-character-class正则表达式中不允许出现空的字符组2
no-ex-assign在try catch语句中不允许重新分配异常变量2
no-extra-boolean-cast不允许出现不必要的布尔值转换2
no-extra-parens不允许出现不必要的圆括号0
no-extra-semi不允许出现不必要的分号2
no-func-assign不允许重新分配函数声明2
no-inner-declarations不允许在嵌套代码块里声明函数["error", "functions"]
no-invalid-regexp不允许在RegExp构造函数里出现无效的正则表达式2
no-irregular-whitespace不允许出现不规则的空格2
no-negated-in-lhs不允许在in表达式语句中对最左边的运算数使用取反操作2
no-obj-calls不允许把全局对象属性当做函数来调用2
no-regex-spaces正则表达式中不允许出现多个连续空格2
quote-props对象中的属性名是否需要用引号引起来2
no-sparse-arrays数组中不允许出现空位置2
no-unreachable在return,throw,continue,break语句后不允许出现不可能到达的语句2
use-isnan要求检查NaN的时候使用isNaN()2
valid-jsdoc强制JSDoc注释["error", {"requireReturn": false, "requireParamDescription": false, "requireReturnDescription": true }]
valid-typeof在使用typeof表达式比较的时候强制使用有效的字符串["error", { "requireStringLiterals": true }]
block-scoped-var将变量声明放在合适的代码块里2
complexity限制条件语句的复杂度0
consistent-return无论有没有返回值都强制要求return语句返回一个值2
curly强制使用花括号的风格["error", "all"]
default-case在switch语句中需要有default语句0
dot-notation获取对象属性的时候使用点号["error", {"allowKeywords": false, "allowPattern": ""}]
eqeqeq比较的时候使用严格等于["error", "smart"]
no-alert不允许使用alert,confirm,prompt语句1
no-caller不允许使用arguments.callee和arguments.caller属性2
guard-for-in监视for in循环,防止出现不可预料的情况0
no-div-regex不能使用看起来像除法的正则表达式2
no-else-return如果if语句有return,else里的return不用放在else里0
no-labels不允许标签语句["error", { "allowLoop": false "allowSwitch": false }]
no-eq-null不允许对null用==或者!=2
no-eval不允许使用eval()2
no-extend-native不允许扩展原生对象2
no-extra-bind不允许不必要的函数绑定2
no-fallthrough不允许switch按顺序全部执行所有case2
no-floating-decimal不允许浮点数缺失数字2
no-implied-eval不允许使用隐式eval()2
no-iterator不允许使用__iterator__属性2
no-lone-blocks不允许不必要的嵌套代码块2
no-loop-func不允许在循环语句中进行函数声明2
no-multi-spaces不允许出现多余的空格2
no-multi-str不允许用\来让字符串换行2
no-global-assign不允许重新分配原生对象2
no-new不允许new一个实例后不赋值或者不比较2
no-new-func不允许使用new Function2
no-new-wrappers不允许使用new String,Number和Boolean对象2
no-octal不允许使用八进制字面值2
no-octal-escape不允许使用八进制转义序列2
no-param-reassign不允许重新分配函数参数0
no-redeclare不允许变量重复声明2
no-return-assign不允许在return语句中使用分配语句2
no-script-url不允许使用javascript:void(0)2
no-self-compare不允许自己和自己比较2
no-sequences不允许使用逗号表达式2
no-throw-literal不允许抛出字面量错误 throw "error"2
no-unused-expressions不允许无用的表达式2
no-void不允许void操作符2
no-warning-comments不允许警告备注[1, {"terms": ["todo", "fixme", "any other term"]}]
no-with不允许使用with语句2
radix使用parseInt时强制使用基数来指定是十进制还是其他进制1
vars-on-topvar必须放在作用域顶部0
wrap-iife立即执行表达式的括号风格[2, "any"]
yoda不允许在if条件中使用yoda条件[2, "never", {"exceptRange": true}]
strict使用严格模式[2, "function"]
no-catch-shadow不允许try catch语句接受的err变量与外部变量重名2
no-label-var不允许标签和变量同名2
no-shadow外部作用域中的变量不能与它所包含的作用域中的变量或参数同名2
no-shadow-restricted-namesjs关键字和保留字不能作为函数名或者变量名2
no-undef不允许未声明的变量2
no-undef-init不允许初始化变量时给变量赋值undefined2
no-undefined不允许把undefined当做标识符使用2
no-unused-vars不允许有声明后未使用的变量或者参数[2, {"vars": "all", "args": "after-used"}]
no-use-before-define不允许在未定义之前就使用变量[2, "nofunc"]
brace-style大括号风格[2, "1tbs", { "allowSingleLine": false}]
camelcase强制驼峰命名规则[2, {"properties": "never"}]
comma-style逗号风格[2, "last"]
consistent-this当获取当前环境的this是用一样的风格[0, "self"]
eol-last文件以换行符结束2
func-names函数表达式必须有名字0
func-style函数风格,规定只能使用函数声明或者函数表达式0
key-spacing对象字面量中冒号的前后空格[2, {"beforeColon": false, "afterColon": true}]
max-nested-callbacks回调嵌套深度0
new-cap构造函数名字首字母要大写[2, {"newIsCap": true, "capIsNew": false}]
new-parensnew时构造函数必须有小括号2
newline-after-var变量声明后必须空一行0
no-array-constructor不允许使用数组构造器2
no-inline-comments不允许行内注释0
no-lonely-if不允许else语句内只有if语句0
no-mixed-spaces-and-tabs不允许混用tab和空格[2, "smart-tabs"]
no-multiple-empty-lines空行最多不能超过两行[2, {"max": 2}]
no-nested-ternary不允许使用嵌套的三目运算符2
no-new-object禁止使用new Object()2
fun-call-spacing函数调用时,函数名与()之间不能有空格2
no-ternary不允许使用三目运算符0
no-trailing-spaces一行最后不允许有空格2
no-underscore-dangle不允许标识符以下划线开头2
no-extra-parens不允许出现多余的括号0
one-var强制变量声明放在一起0
operator-assignment赋值运算符的风格0
padded-blocks块内行首行尾是否空行[2, "never"]
quote-props对象字面量中属性名加引号0
quotes引号风格[1, "single", "avoid-escape"]
semi强制语句分号结尾[2, "always"]
semi-spacing分后前后空格[2, {"before": false, "after": true}]
sort-vars变量声明时排序0
space-before-blocks块前的空格[2, "always"]
space-before-function-paren函数定义时括号前的空格[2, {"anonymous": "always", "named": "never"}]
space-infix-ops操作符周围的空格[2, {"int32Hint": true}]
keyword-spacing关键字前后的空格2
space-unary-ops一元运算符前后不要加空格[2, { "words": true, "nonwords": false}]
wrap-regex正则表达式字面量用括号括起来2
no-var使用let和const代替var0
generator-star-spacing生成器函数前后空格[2, "both"]
max-depth嵌套块深度0
max-len一行最大长度,单位为字符0
max-params函数最多能有多少个参数0
max-statements函数内最多有几个声明0
no-bitwise不允许使用位运算符0
no-plusplus不允许使用++ --运算符0
indent强制一致的缩进风格2
no-delete-var不允许使用delete操作符2
no-proto不允许使用__proto__属性2

ESLint 提供了大量内置的规则,这里是它的规则列表 ESLint Rules,除此之外你还可以通过插件来添加更多的规则。

推荐团队规范开源配置

上述是一些基础的配置,具体的使用呢可以自己去配置,一般这类规则的配置可以参照市面上比较流行的规范,使用别人的规范加自己的配置进行结合。市面上目前最为流行的开源配置使用最多的是airbnb团队的配置。下面这些配置值得推荐:

如何使用

想要使用别人的配置通常只需要下载对应的依赖并且加入到extends继承下来即可,可以配置为字符串或者数组均可。

{
    extends: [
        'eslint:recommended', // 是 ESLint 官方的扩展,内置推荐规则
        'plugin:vue/essential', // 是插件类型扩展
        'eslint-config-standard', // eslint-config 开头的都可以省略掉前面 直接使用standard即可
        '@vue/prettier', // @开头扩展和 eslint-config 一样,只是在 npm 包上面加了一层作用域 scope;
        './node_modules/coding-standard/.eslintrc-es6' // 一个执行配置文件的路径
    ]
}
​

如何使用插件 plugins

ESlint的插件是干嘛的:

首先我们需要知道的Eslint本质只是一个代码检测工具,默认情况下也只能检测js文件,如果我们需要在工程化中加入去兼容其他语法例如[.vue]、[.jsx]等其他格式的文件时就没有办法实现,所以我们需要加入一些插件来实现对非js格式的文件进行检测。

# 如何配置plugin

ESlint相关的插件有两种命令名形式,带命名空间的和带的,比如

  • eslint-plugin-xxx 以eslint-plugin-开头的都可以直接省略掉 类似上面的extends继承规则只需要 xxx就行
  • @开头表示带命名空间的就正常引入即可
{   
  plugins: [        
    'jquery',// 是指 eslint-plugin-jquery        
    '@jquery/jquery',  // 是指 @jquery/eslint-plugin-jquery        
    '@foobar', // 是指 @foobar/eslint-plugin    ] 
}

当需要基于插件进行 extends 和 rules 的配置的时候,需要加上插件的引用,比如:

{
    plugins: [
        'jquery',   // eslint-plugin-jquery
        '@foo/foo', // @foo/eslint-plugin-foo
        '@bar,      // @bar/eslint-plugin
    ],
    extends: [
        'plugin:jquery/recommended',
        'plugin:@foo/foo/recommended',
        'plugin:@bar/recommended'
    ],
    rules: {
        'jquery/a-rule': 'error',
        '@foo/foo/some-rule': 'error',
        '@bar/another-rule': 'error'
    },
}

以上配置来自 ESLint plugins

热门开源规范推荐

如何知道某个扩展有哪些规则可以配置,以及每个规则具体限制? 这里直接给出业内著名且使用比较多的规则列表的快速链接:

规则的优先级

  • 如果 extends 配置的是一个数组,那么最终会将所有规则项进行合并,出现冲突的时候,后面的会覆盖前面的;
  • 通过 rules 单独配置的规则优先级比 extends 高;
其他配置

配置当前目录为 root

ESLint 检测配置文件步骤:

    1. 在要检测的文件同一目录里寻找 .eslintrc.* 和 package.json;
    1. 紧接着在父级目录里寻找,一直到文件系统的根目录;
    1. 如果在前两步发现有 root:true 的配置,停止在父级目录中寻找 .eslintrc;
    1. 如果以上步骤都没有找到,则回退到用户主目录 ~/.eslintrc 中自定义的默认配置;

通常我们都习惯把 ESLint 配置文件放到项目根目录,因此可以为了避免 ESLint 校验的时候往父级目录查找配置文件,所以需要在配置文件中加上 root: true。

{
    root: true,
}

参考:ESLint配置文件.eslintrc参数说明

如何配置

ESLint 支持 3 种配置方式:

  • 命令行:不推荐,不做介绍;
  • 单文件内注释:不推荐,不做介绍;
  • 配置文件:配置文件的类型可以是好几种,比如:.js、.yml、json 等。推荐使用 .eslintrc.js,如果规则很少也可以配置在package.json当中。
  1. 安装 npm i eslint -D

  2. 初始化配置文件./node_modules/.bin/eslint --init 或者npx eslint --init都一样,会在根目录生成一个.eslintrc.js

  3. 通过上面的介绍可以自己为自己配置一系列规则,那么我们如何触发呢?

    1. 校验单个文件

      npx eslint a.js b.js
      
    2. 校验一个目录

      npx eslint src
      
    3. 校验非js格式的文件,通常Eslint只能校验js文件,如果我们要校验.vue.jsx文件该怎么做呢,只配置vue-eslint-parser的解析器是不够的,还需要让Eslint在查找文件的时候找得到.vue文件。可以通过--ext指定需要校验的文件格式

      npx eslint --ext .js,.jsx,.vue src  
      
    4. 在上面的规则当中进入官方文档的配置规则,在全部规则的列表里面带有标志的规则表示可以被Eslint自动修复,那么我们如何自动修复呢?只需要通过--fix的命名即可,和检验文件的命令相似,只需要再加上修复命令即可

      npx eslint --fix src
      
    5. 当然在项目中每次自己输入太过于繁琐也不好记,我们可以在package.json中配置检测和修复命令:

      {
          "scripts": {
              "lint": "npx eslint --ext .js,.jsx,.vue src",
              "lint:fix": "npx eslint --fix --ext .js,.jsx,.vue src",
          }
      }
      
    6. 过滤自己不需要检测的文件,在某些情况下我们不需要检测某些文件,或者由于某些原因在当前场景下不想去检测某个文件,我们只需要在项目根目录去创建.eslintignore文件,在其中指定目录或者文件即可,路径是以根目录为相对地址的路径。同时Eslint是默认忽略/node_modules/的文件的,这个目录不需要配置。

冷知识

  1. sourceType 有两个值,script 和 module。 对于 ES6+ 的语法和用 import / export 的语法必须用 module.
  2. eslint --init 只有在选择 "To check syntax, find problems, and enforce code style" 才可以选择 airbnb, standard, recommended 标准。
  3. 有时候在前端项目中存在前端和 node 的代码共存的情况,只要在 env 中配置好 browser: true, node: true 就可以把兼容不同环境的全局变量兼容进来,例如 nodejs 中的 global, process 等等。
  4. 规则强度是 airbnb > standard > recommended
  5. 正常情况不会去修复一个文件,都会在项目上配置命令一次修复全局
  6. 配合Prittier可以更好的工作
  7. 配合Vscode实现自动保存,需要先下载Eslint插件,首选项 -> 设置 -> 搜索 "autofix". Auto Fix On Save。 就可以在保存的时候自动修正了。

总结

  • eslint是干嘛的,如何生成使用,配置
  • 如何配置规则,有哪些常用规则,如何触发
  • 如何使用别人的开源规则,如何继承,如何修改继承的规则
  • 如何使用插件,插件是干嘛用的,如何配合使用
  • 如何去检测文件和自动修复文件以及配置检测修复命令
  • 如何去检测非js格式的文件

对于基础入门我们只需了解这些知识就可以,在后续我们再来了解如何在VueReact项目中引入Eslint及如何使用集成