Madogiwa Blog

主に技術系の学習メモに使っていきます。

ESLintのカスタムルールの作り方MEMO📝

ESLintのカスタムルールを作る機会があったので手順とかメモ📝

公式Doc

eslint.org

ESLintのカスタムルールの作り方MEMO

カスタムルールを配置するディレクトリを作成する

以下のような形で任意のディレクトリを作成します。

mkdir eslint/rules

カスタムルールの雛作る

公式Docを参考にRuleの雛形を作成します。(以下はすべてのコードでsample rule!!の警告を出すLint)

"use strict";

/** @type {import('eslint').Rule.RuleModule} */
module.exports = {
  meta: {
    type: "suggestion", // type (string) indicates the type of rule, which is one of "problem", "suggestion", or "layout":

    docs: {
      description: "sample rule",
    },
    fixable: null, // fixable (string) is either "code" or "whitespace" if the --fix option on the command line automatically fixes problems reported by the rule
    schema: [], // no options
  },
  /** @param {RuleContext} context */
  create: function (context) {
    return {
      /** @param {Program} node */
      Program(node) {
        context.report(node, "sample rule!!");
      },
    };
  },
};

カスタムルールを実行するようにconfig及び実行コマンドを修正

作成したファイル名(拡張子なし)をrulesに追加して有効化し、

  "rules": {
++  "sample-rule": 1
  },

--rulesdir カスタムルールを配置したディレクトリパスを付けてESLintを実行するようにする。

# 例)
$ npx eslint app/javascript spec/javascript --ext .vue,.js,.ts --rulesdir eslint/rules

カスタムルールを作成

ESLintはASTをゴニョゴニョしてコードを解析できるので検知したいコードのASTを以下のサイトで解析してコードを検討する。

astexplorer.net

例えばconsole.log("Hello world!!")を検知するようなルールを作りたい場合は以下のようなコードで検知できる。

"use strict";

/** @type {import('eslint').Rule.RuleModule} */
module.exports = {
  meta: {
    type: "problem",

    docs: {
      description: "sample rule",
    },
    fixable: "code",
    schema: [], // no options
  },
  /** @param {RuleContext} context */
  create: function (context) {
    return {
      /** @param {CallExpression} node */
      CallExpression(node) {
        if (
          node.callee.type === "MemberExpression" &&
          node.callee.object.type === "Identifier" &&
          node.callee.property.type === "Identifier" &&
          node.callee.object.name === "console" &&
          node.callee.property.name === "log" &&
          node.arguments[0].type === "Literal" &&
          node.arguments[0].value === "Hello world!!"
        ) {
          context.report(node, "sample rule!!");
        }
      },
    };
  },
};

以下のように検知できる🎉

$ eslint app/javascript spec/javascript --ext .vue,.js,.ts --rulesdir eslint/rules
  23:1  warning  sample rule!!                 sample-rule

終わりに

ESLintのカスタムルール、意外と手軽に作れて便利ですね🙌

参考

qiita.com

techblog.yahoo.co.jp