React 始めたので vim の jsHint を ESLint に変更した話

いまさらですが、React 書き始めました。すると、これまで利用していた jsHint ではエラーや警告が誤検出されるので、この対策をした時のメモになります。

React なら ESLint ですわ

React は JSX など独特な書き方がありますし、これからは ES6 になりますので、これらをうまく解釈できるものはないか? と調査すると jsHint で JSX をチェックする JSXHint というラッパーがありました。

GitHub - STRML/JSXHint: Wrapper around JSHint for linting JSX files. 100% compatible with existing tools using JSHint.

よし、これを試すか、、と思ったらのっけから

Don’t use JSXHint anymore if you can switch to ESLint.

ということで、これまでお世話になった jsHint を辞めて ESLint に Switch しましょう。どうも現代では、React で書くなら ESLint を使うのが当たり前のようです。*1

ESLint セットアップ

私の開発環境(MAC OS Sierra)に ESLint を導入します。

eslint.org

導入方針

ESLint についていろいろ調べたところ、グローバルにインストールするのではなく、アプリケーション毎にローカルにインストールして、それぞれ専用の設定をして使用することができるようです。確かに、React 使う時や Angular 使う時やその他でコンフィグレーション内容が大きく変わりそうなので、ローカルにインストールする方が理に適っています。

また、ESLint がローカルにインストールされていれば、それをグローバル的に利用可能とする “eslint-cli” というツールを発見、便利そうなのでこれも併せて導入します。

www.npmjs.com

(1) ESLint をローカルにインストール

前提として node.js がインストールされている必要があります。ちなみに、私の場合は、nodebrew で利用する node.js のバージョンを選択できるようにしています。

$ node -v
v7.8.0

$ npm -v
4.2.0

以下のようにローカルに ESLint をインストールします。今回 React が前提なので eslint-plugin-react も必要となります。

$ npm install --save-dev eslint eslint-plugin-react

ちなみにインストールした ESLint のバージョンは 3.19.0 でした。

$ eslint -v
v3.19.0

(2) ESLint 初期設定

ESLint を使用するには、予めルールなどを定義した設定ファイルを作成する必要がありますが、自作するのは結構メンドくさそうです。ですが最近では “eslint –init” で簡単に設定ファイルを作成できるようです。

というか、本家の Getting Start のページを見ると、むしろこの手順で初期化することが前提となっていますね。

Getting Started with ESLint - ESLint - Pluggable JavaScript linter

さっそくやってみましょう。
今回は対話(質問に答える)形式で初期化する方法で実行してみました。

$ ./node_modules/.bin/eslint --init
? How would you like to configure ESLint? Answer questions about your style
? Are you using ECMAScript 6 features? Yes
? Are you using ES6 modules? Yes
? Where will your code run? Browser
? Do you use CommonJS? No
? Do you use JSX? Yes
? Do you use React? Yes
? What style of indentation do you use? Spaces
? What quotes do you use for strings? Single
? What line endings do you use? Unix
? Do you require semicolons? Yes
? What format do you want your config file to be in? JavaScript
Successfully created .eslintrc.js file in /Users/naoki/DEV/SANDBOX/react

成功です。下記のようにESLint の設定ファイル “.eslintrc.js” ができています。

$ cat .eslintrc.js

module.exports = {
    "env": {
        "browser": true,
        "es6": true
    },
    "extends": "eslint:recommended",
    "parserOptions": {
        "ecmaFeatures": {
            "experimentalObjectRestSpread": true,
            "jsx": true
        },
        "sourceType": "module"
    },
    "plugins": [
        "react"
    ],
    "rules": {
        "indent": [
            "error",
            4
        ],
        "linebreak-style": [
            "error",
            "unix"
        ],
        "quotes": [
            "error",
            "single"
        ],
        "semi": [
            "error",
            "always"
        ]
    }
};

(3) eslint-cli をグローバルにインストール

ここで、冒頭で説明した “eslint-cli” をインストールしておきます。これで、わざわざ “./node_module/.bin/eslit” とせずに “eslint” だけで実行できるようになります。

$ mpn install eslint-cli -g

(4) ESLint の動作確認テスト

ESLint 実行環境が整ったので動作確認します。テスト対象としたコードは、React Tutorial で作成した “index.js” です。

$ eslint src/index.js

/Users/naoki/DEV/SANDBOX/react/src/index.js
    5:10  error  'Square' is defined but never used            no-unused-vars
    6:3   error  Expected indentation of 4 spaces but found 2  indent
   13:7   error  'Board' is defined but never used             no-unused-vars
   14:3   error  Expected indentation of 4 spaces but found 2  indent
   15:5   error  Expected indentation of 6 spaces but found 4  indent
   17:3   error  Expected indentation of 4 spaces but found 2  indent
   18:5   error  Expected indentation of 6 spaces but found 4  indent
   40:7   error  'Game' is defined but never used              no-unused-vars
   41:3   error  Expected indentation of 4 spaces but found 2  indent
   42:5   error  Expected indentation of 6 spaces but found 4  indent

   ... 省略 ...

  128:5   error  Expected indentation of 6 spaces but found 4  indent
  129:5   error  Expected indentation of 6 spaces but found 4  indent
  130:7   error  Expected indentation of 8 spaces but found 6  indent
  133:3   error  Expected indentation of 4 spaces but found 2  indent

✖ 48 problems (48 errors, 0 warnings)

ご覧の通りたくさんのエラーが出てしまいました。よく見ると、そのほとんとがインデント数が変だと言っていますが、これは誤検出です。むしろ設定ファイルのタブ数の設定に問題がありますので “.eslintrc.js” の “rules.indent” を 4 から 2 に変更します。

   "indent": [
      "error",
      2
   ],

再度実行してみます。

$ eslint src/index.js

/Users/naoki/DEV/SANDBOX/react/src/index.js
   5:10  error  'Square' is defined but never used  no-unused-vars
  13:7   error  'Board' is defined but never used   no-unused-vars
  40:7   error  'Game' is defined but never used    no-unused-vars

✖ 3 problems (3 errors, 0 warnings)

だいぶマシになりましたが、3箇所エラーが検出されてしまいました。うむむ。
こちらは ES6 のプログラム的には問題ない(never used となっていますが JSXから参照しています)ので、やはり ESLint の誤検出で、設定に問題があります。

(5) no-unused-vars 問題を解決する

こちらに解決策がありました。ありがたや。

ESLintでReactを扱う - Qiita

また、eslint-plugin-react のページでも、no-unused-vars を prevent するルールについての記述がありますね。

eslint-plugin-react

ということで、次のルールを “.eslintrc.js” に加します。

  "rules": {
    "react/jsx-uses-react": "error",
    "react/jsx-uses-vars": "error",
  }

これで再実行して Lint エラー(誤検出)が全て無くなりました。OKです。

vim のチェッカを jsHint から ESLint に変更

最終的な目的は、vim で自動的に Lint チェックしてもらうことなので、.vimrc の設定を変更します。

具体的には、下記の通り “let g:syntastic_javascript_checkers” の値を “jshint” から “eslint” に変更するだけです。

let g:syntastic_mode_map = { 'mode': 'active',
  \ 'active_filetypes': [],
  \ 'passive_filetypes': [] }
let g:syntastic_javascript_checkers = ['eslint']
let g:syntastic_check_on_wq = 0

これで、vim で編集する javascript の コードは、ESLint でチェックすることが可能となりました。これでとりあえずの作業は全て完了です。

まとめ

  • React なら ESLint を使え
  • ローカルインストールすれば、アプリケーション毎に専用の設定ができる
  • ESLint の設定ファイルを一から自作するのはちょっと大変だが、"eslint –init" でこの作業を簡単にすることができる

今回はこれくらいです。 これからは ES6 必須ですし、しばらくは ESLint のお世話になりそうです。ということは、さらにきめ細かな設定方法や、様々なツールやエディタとの連携方法なども習得していく必要がありますね。

*1:世間の速さに追いついていないです。キャッチアップしないとだめです