ESLintで再帰的なファイルマッチが動かない
以下のように、いくつかの深さを持ったJavaScript、もしくはTypeScriptファイルに対してESLintを再帰的に適用させる場合、globパターン(**
)を利用してファイルマッチさせるかと思います。
src
|--index.js
|--app
| |--app.js
| |--util
| |--hoge.js
| |--data
| |--fuga.js
そこで、 package.json
には以下のように script を定義します。
"scripts": {
"lint": "eslint src/**/*.js"
}
しかし、この script を実行しても1つのファイルからしかエラーが検出されません。
$ yarn lint
yarn run v1.13.0
$ eslint src/**/*.js
eslint-test/src/app/app.js
1:1 error Unexpected console statement no-console
✖ 1 problem (1 error, 0 warnings)
対処法
実はglobパターンを利用してファイルを再帰的にマッチさせるには、シングルクォーテーションで囲んであげる必要があります。
"scripts": {
"lint": "eslint 'src/**/*.js'"
}
こうすると、全てのファイルからエラーが検出されるようになります。
$ yarn lint
yarn run v1.13.0
warning package.json: No license field
$ eslint 'src/**/*.js'
root/src/app/app.js
1:1 error Unexpected console statement no-console
root/src/app/util/data/fuga.js
1:1 error Unexpected console statement no-console
root/src/app/util/hoge.js
1:1 error Unexpected console statement no-console
root/src/index.js
1:1 error Unexpected console statement no-console
✖ 4 problems (4 errors, 0 warnings)
やったね 😊
補足
なぜこのように動作するのかコメントで指摘いただいたので、その点を記載します。
scripts
に記述したコマンドは bin/sh
によって実行されます。そこでGlobにマッチしたファイルリストを列挙してESLintに渡すことになるのですが、シングルクォートで囲むことによってGlobの解釈自体がESLintで行われるようになります。そのため、意図した通りのファイルがマッチして動作するようになっています。 (私の環境のシェルでは /**/*.js
をフォルダ構造でマッチさせていたため、意図したファイルリストがESLintに渡されなかった模様)
なお、Windows環境では scripts
コマンドの実行に cmd.exe
を使いますが、 cmd.exe
ではシングルクォートを引数として正しく認識しません。そのため、ダブルクォートを使用する必要があります。
※ この動作/検証は ESLint 6.5.1 で確認しています
参考
ESLint 5.1.0 - No files matching the pattern for several repos