如何编写一个自定义的 eslint 规则?

准备

正文

开始编写 eslint 插件

官方推荐使用 yeoman generator-eslint 脚手架快速生成 eslint plugin模版,不过已经3年没有更新了,感兴趣可以看看这个脚手架的源码。

编写规则

编写一个规则,其实就是在 eslint 提供的 AST 中,找到我们需要检查的 AST 节点,对其进行判断,如何符合条件,就抛出相关提示。

遍历 AST 节点

一个最简单的 rule 对象,只需要声明一个 create 属性即可。参考以下代码:

module.exports = {
    create: function(context) {
        // declare the state of the rule
        return {
            ReturnStatement: function(node) {
                // at a ReturnStatement node while going down
            },
            // at a function expression node while going up:
            "FunctionExpression:exit": checkLASTSegment,
            "ArrowFunctionExpression:exit": checkLASTSegment,
            onCodePathStart: function (codePath, node) {
                // at the start of analyzing a code path
            },
            onCodePathEnd: function(codePath, node) {
                // at the end of analyzing a code path
            }
        };
    }
};

上述代码中,create 方法返回的对象,就是 AST 节点 “遍历器” 的集合。

我们可以直接声明 estree 中支持的 AST types。下面这段代码的作用,就是遍历所有的 return 语句,并执行定义的回调函数。

同时,eslint 所依赖的 espree,也支持使用类似 css 选择器的 selector 语法,对 AST types 进行组装。

下面的代码会遍历 new 语句中的字面量参数。

如果对特定代码片段的 AST 结构非常陌生,可以考虑编写一段 demo 代码,使用 espree 进行解析,可以根据得到的 AST 来编写“遍历器”。

context 相关 api 可以参考官方文档的说明。

抛出错误提示

context 对象提供了一个 report 方法,用于抛出警告和错误提示。

最基本的用法如下:

report 方法也支持变量插值:

Example

让我们来实战一下,现在我们需要限制用户调用 new Date() 方法。

  1. 如果你不知道一个 new Date() AST 节点是什么样子的,可以试试编写demo代码,得到一个初始化的 AST 结构

    AST

    可以发现,new Date() 方法的调用,在 AST 中的 type 为 NewExpression。这里的 init其实就是 eslint 中的 node 节点。

  2. 现在我们需要判断,一个 AST 节点,是否是 new Date()

  3. 找到正确的代码语句后,我们需要抛出提示

  4. 现在你会发现,一个自定义的规则就大功告成了

使用规则

plugins + rules

eslint 提供了接入 plugin 的方式,使用 plugins字段即可。需要注意的是,这里配置的 plugin 名称,不需要再声明 eslint-plugin 的前缀。

引入 plugin 后,就可以直接在 rules 中添加该插件中定义的各个规则。与 eslint 内置的规则不同,使用 plugin 的规则,需要声明命名空间,采用 'namespace/rule-name' 的形式。

如果你编写的 plugin 尚未发布 npm 包,可以使用以下方式把一个开发中的包加入到当前工作目录下的 node_modules 中

extends

一个插件可以提供预设好的多个规则,让使用者直接引入。

plugin内的配置如下:

使用者的配置如下:

参考内容

Last updated

Was this helpful?