深入探索Eslint【上篇】

558 阅读3分钟

历史(History)

怎么使用 (How to use)

  • .eslintrc配置说明

如何写一个规则(Write a rule)

  • AST
  • code path analysis
  • Eslint工作流程

简单聊下mpx的eslint

历史

c语言的lint早在1979年诞生出来,用于解决代码不严谨导致编译执行不通过,随着javascript发展的迅猛,javascript本身设计上的问题暴漏了出来。

2002年Douglas Crockford可能开发了第一款js语法检测工具——JSLint,并于2010年开源。jsLint的缺点也很明显,不能配置,Douglas Crockford并不觉得是一个问题,

Anton Kovalyov 吐槽:「JSLint 是让你的代码风格更像 Douglas Crockford 的而已」

2011年Anton Kovalyov fork了JSLint开发了JSHint,特点就是可配置

2013年Nicholas C. Zakas觉得JSHint也无法满足自己的定制化规则需求,Zakas 还设想发明一个基于 AST 的 lint,可以动态执行额外的规则,同时可以很方便的扩展规则。同年6月Zakas 发布了全新的 lint 工具——ESLint。同一时间还有一个类似的lint叫JSCS也出现了,后来JSCS觉得原理和ESLint太过相似就合并到了ESLint。ESLint刚出现并不可取代JSHint,ESLint利用AST需要解析代码,相对JSHint要慢一些。

ESLint的逆袭在2015,ES2015的规范正式发布,react的流行,jsx语法需要支持,ESLint本身也不支持,正因为它的扩展性,不仅可以扩展规则,甚至连解析器也可以替换。从此ESLint代替了JSHint的位置

怎么使用

Install

npm install eslint --save-dev

Init

./node_modules/.bin/eslint --init

Use

./node_modules/.bin/eslint yourfile.js

Init之后会生成一个.eslintrc文件,可以在这个文件中添加规则,扩展,变更解析器各种操作

ESlint被设计成完全可配置的,它主要的配置方式有两种

  • Configuration Comments - 使用注释

  • Configuration Files - 使用.eslintrc.*文件配置,或者直接在 package.json 文件里的 eslintConfig 字段指定配置。再者还可以用CLI来指定一个任意的配置文件

注释方式

/* eslint eqeqeq: 0, curly: 2 */
if (0 == false) console.log(1)

/* eslint-disable */
alert('foo');
/* eslint-enable */
alert('foo');

/* eslint-disable no-alert, semi */
alert('foo');

/* eslint-disable-next-line */
alert('foo');

alert('foo');/* eslint-disable-line */

/* eslint-env node, mocha */
/* global var1:writable, var2:writable */

文件方式

多种文件格式,优先顺序如下

  • .eslintrc.js

  • .eslintrc.yaml

  • .eslintrc.yml

  • .eslintrc.json

  • .eslintrc

  • package.json

    your-project ├── .eslintrc ├── lib │ └── source.js └─┬ tests ├── .eslintrc //相对于test.js 优先级最高,且合并上层级配置【若设置了"root": true则不合并】 └── test.js

整体优先级

  1. 行内配置 /*eslint-disable*/
  2. 命令行选项 --rule -c
  3. .eslintrc.* 文件

具体配置

module.exports = {
    "env":{ 
        "es6": true
        "browser": true,
        "node": true
     },
    "parserOptions": {
        "ecmaVersion": 6,
        "sourceType": "module",
        "ecmaFeatures": {
            "jsx": true
        }
     },
    "parser": "esprima", 
    "extends": [
        "eslint:recommended",
        "plugin:mpx/mpx-essential",
        "./node_modules/coding-standard/eslintDefaults.js",        
    ], // string[] | string
    "plugins": ["vue", "react", "mpx"],
    "rules": {
        "eqeqeq": "off",
        "no-alert": "2",
        "semi": "warn",
        "no-undef": "0",
        "quotes": ["error", "double"],
        "no-restricted-syntax": ["error", "CallExpression[callee.name='require']"]
    },
    "processor": "a-plugin/markdown",
    "overrides": [
        {
            "files": ["*.md"],
            "processor": "a-plugin/markdown"
        },
        {
            "files": ["**/*.md/*.js"],
            "rules": {
                "strict": "off"
            }
        }
    ],
    "globals": {
        "Promise": "off",
        "var1": "writable",
        "var2": "readonly"
    },
    "settings": {
        "sharedData": "Hello"
    },
    "root": true
}

具体一个个字段来看

  • env:就是根据不同环境切换规则,比如es6:true //默认 就会识别es6语法
  • parserOptions:parser解析器会用到的参数
  • parser: eslint默认的解析器是espree 例如vue也有自己的解析器vue-eslint-parser
  • processor: 处理器,可以在预处理中转换 JavaScript 代码
  • extends: 继承一些其他的配置,有挺多种形式
  • plugins:顾名思义,插件。拓展处理其他语言
  • overrides:针对某个文件进行特殊处理
  • globals:全局变量,"no-undef"规则下可不报错
  • settings:提供的内容将给所有规则使用
  • root:有种停止冒泡的感觉
  • rules:配置规则的处理

.eslintignore文件中的目录和文件path将不被处理

cli不过多赘述

剩下内容见【下篇】

历史 zhuanlan.zhihu.com/p/32297243

原理 zhuanlan.zhihu.com/p/53680918

官网 eslint.cn/