eslint

文章目录
  1. 1. 使用
    1. 1.1. 初始化
    2. 1.2. 常用插件
    3. 1.3. 部分关闭eslint检测
    4. 1.4. autofix
    5. 1.5. 配合git commit
    6. 1.6. plugins 和 extends
    7. 1.7. 其它问题
  2. 2. 原理
    1. 2.1. 插件开发

参考资料

使用

初始化

# 初始化eslint
./node_modules/.bin/eslint --init
# 全局安装的esint
eslint --init
// .eslintrc.js
module.exports = {
env: {
browser: true,
es6: true,
node: true
},
globals: {
Atomics: "readonly",
SharedArrayBuffer: "readonly",
},
// 指定传给 parser 的信息,eslint使用的默认是Espree
parserOptions: {
ecmaVersion: 2018,
sourceType: "module",
},

extends: [
"eslint:recommended",
// "plugin:vue/recommended"
// "plugin:react/recommended"
// "plugin:react-hooks/recommended"
],
rules: {
indent: ["error", 2],
},
};

常用插件

部分关闭eslint检测

  • 使用.eslintignore文件
  • 在代码中用注释“圈住”不需要检查的部分
    /* eslint-disable */
    alert('foo');
    /* eslint-enable */

autofix

配合git commit

  • 必要时,可以使用git commit --no-verify绕过验证直接提交 【参考资料
  • 假如不生效,可以排查一下.git/hooks/目录里是否有pre-commit文件 【参考资料
    // npm i -D pre-commit

    // package.json
    {
    ...,
    "pre-commit": ["lint"],
    "script": {
    "lint": "eslint ./"
    }
    }

plugins 和 extends

extends可以直接继承许多rules,但是plugins需要自己手动引入rules;二者选其一即可,大部分情况下都是使用extends;【参考资料

// eslintrc.js
module.exports = {
extends: [
"eslint:recommended",
"plugin:react/recommended",
],


plugins: [
"react", // eslint-plugin-react
],
rules: {
"react/display-name": 2 // 手动引入plugins里的rules
}
}

其它问题

原理

  • 使用esprima生成ast
  • 开发rule插件来拓展各种检查规则

插件开发

参考资料】 【官方文档

  • 和babel一样,利用ast钩子函数
  • docs是出错提示相关配置
  • 另外可以留意下autofix的实现(应该也是类似babel吧,修改ast树,然后再generate)
    module.exports = {
    meta: {
    docs: {
    description: "no console.time()",
    category: "Fill me in",
    recommended: false
    },
    // 是否支持autofix;如果可以的话,需要补充fix函数
    fixable: null,
    // console报错信息描述
    messages: {
    avoidMethod: "console method '{{name}}' is forbidden."
    }
    },

    create: function(context) {
    return {
    // 键名为ast中选择器名
    "CallExpression MemberExpression": node => {
    // 如果在ast中满足以下条件,就用 context.report() 进行对外警告
    if (node.property.name === "time" && node.object.name === "console") {
    context.report({
    node,
    messageId: "avoidMethod",
    data: {
    name: "time"
    }
    });
    }
    }
    };
    }
    };

    // autofix
    context.report({
    node: node,
    message: "Missing semicolon",
    fix (fixer) {
    return fixer.insertTextAfter(node, ";");
    }
    });