count0.org

ESLintのルール作成に挑戦

18 March 2019 js

JavaScriptを書くときに欠かせないのがESLint(そしてprettier)。ふと思う。ESlintで独自ルールはどう書くのか?この単純な疑問を解決するために、自作ルールを書いてみた。

https://github.com/pipboy3000/eslint-plugin-no-hyogo-police

とても簡単な無限ループを書いてしまったときに警告するルールである。リポジトリ名で出落ち感はある。実用性はゼロだ。

while(true) {
  alert('貴様はこれを閉じれない')
}

上記のようなコードを書くと、They are watching you from Hyogo.という警告メッセージを表示するようになっている。

ESLintは仕組みが整っているので、簡単に実現できた。whileの無限ループの部分だけリポジトリからコードを抜粋すると

module.exports = {
  create: function(context) {
    function report(node) {
      context.report({ node, messageId: 'theyWatch' })
    }
    return {
      WhileStatement: function(node) {
        if (
          node.test.type !== "BinaryExpression" &&
          node.test.name !== "undefined" &&
          node.test.value !== null &&
          node.test.value !== false &&
          node.test.value !== 0
        ) {
          report(node)
        }
      }
    };
  }
};

WhileStatementBinaryExpressionはなんぞや?これはAST Exploerで得られた抽象構文木である。

話は前後するが、最初にテストコードを書く。これも仕組みが整っている。テストコード全文を掲載すると

var RuleTester = require("eslint").RuleTester;

var tester = new RuleTester();
tester.run('infinite_loop', require('../../../lib/rules/infinite-loop'), {
  valid: [
    { code: "while(n < 3){}" },
    { code: "while(false){}" },
    { code: "while(null){}" },
    { code: "while(undefined){}" },
    { code: "while(0){}" },
    { code: "for(var i = 0; i < 10; i++) {}" }
  ],
  invalid: [
    { code: "while(true){}", errors: ["They are watching you from Hyogo."] },
    { code: "while(1){}", errors: ["They are watching you from Hyogo."] },
    { code: "while('a'){}", errors: ["They are watching you from Hyogo."] },
    { code: "for(;;){}", errors: ["They are watching you from Hyogo."] },
    { code: "for(var i = 0;;i++){}", errors: ["They are watching you from Hyogo."] },
    { code: "for(var i = 0; i = 1;i++){}", errors: ["They are watching you from Hyogo."] }
  ]
})

validにOKなコード、invalidに警告を出したいコードと警告メッセージを書く。このテストがオールグリーンになるまでルールの方を書いていくという流れ。


予想よりも簡単にESLintの独自ルールが書けた。仕組みが整っているのは素晴らしい。ルールに穴があるし、頭に書いたように実用性ゼロだが、まあいいでしょう。

余談だが、GitHubでコードを公開している警察はあるのか調べたら、あった。すごくサイバーだ。

ご参考に