es2015をairbnb流にESLintするための設定

ブラウザをターゲットとするUI開発では、Javascriptの開発ツールが重要になります。

機械的なバグチェック用途では、lintツールが主力のツールとなり、いま、ES2015規格に沿った開発が浸透しつつあることもあって、ESLintが有力な選択肢になっています。

ESLintはチェック項目を細かく設定・拡張でき、ユーザーごとの流儀に従ったカスタマイズ設定が流通しています。

今回は、ES2015向けのユーザー設定として、airbnbが自社開発をターゲットにメンテナンスしている eslint-config-airbnbを採用しました。airbnb流のカスタマイズでは、React.jsのJSXコードもそのままチェックできます。

eslint-config-airbnbのインストールと設定

公式サイトの手順に沿って、下記のシェルコマンドを実行すると、(グローバル環境ではなく)npmのプロジェクトとしてnode_modulesに追加されます。

(
  export PKG=eslint-config-airbnb;
  npm info "$PKG" peerDependencies --json | command sed 's/[\{\},]//g ; s/: /@/g' | xargs npm install --save-dev "$PKG"
)

そのため、npmの実行環境がインストール済になっていることと、npmパッケージ利用手順の基礎的な知識は暗黙の前提となっています。

また、この手順ではeslintコマンドはnpm経由で呼び出すことになるため、以下のような追加設定をpackage.jsonに追加しました。

scriptsエントリのlintの項の設定により、npm run lintというコマンド経由でeslintを呼べるようにしています。

"scripts": {
      "lint": "eslint src/*jsx",
    },
    "eslintConfig": {
      "extends": "airbnb",
	  "env": {
        "browser": true,
        "node": true
      },
      "rules": {
        "no-invalid-this": 2,
        "no-useless-call": 2,
        "no-class-assign": 2,
        "require-yield": 2,
        "constructor-super": 2,
        "no-this-before-super": 2
      }
    }

なお、eslintConfigのエントリは、一般的には.eslintrcに設定する内容をpackage.jsonにまとめたものです。

extendsでairbib拡張の使用を指定しています。envは、たとえばbrowserのwindowやdocumentなどのプロパティを利用するコードが妥当であることを宣言しています(これがないと、’document’ is not definedといったエラーになる)。

rulesは追加の自前設定です。ここでは この記事のコメントの推奨設定をためしに追加してみました。

この設定によりnpm run lintコマンドでコードのlintチェックをかけられるようになり、以下のような出力を得られます。

7:32  error  Component should use es6 class instead of createClass                                react/prefer-es6-class
   16:5   error  Do not use setState in componentDidMount                                             react/no-did-mount-set-state
   53:13  error  Visible, non-interactive elements should not have mouse or keyboard event listeners  jsx-a11y/no-static-element-interactions
   59:33  error  Component should use es6 class instead of createClass                                react/prefer-es6-class
   59:33  error  Declare only one React component per file                                            react/no-multi-comp
   68:5   error  Do not use setState in componentDidMount                                             react/no-did-mount-set-state
  105:13  error  Visible, non-interactive elements should not have mouse or keyboard event listeners  jsx-a11y/no-static-element-interactions

なお、このようにLintがルール不適合な箇所を検出した場合、npmコマンドじたいも”Exit status 1″としてエラー終了となりますが、これはスクリプト自動実行を想定した仕様のようです。

ES2015とReact.jsのインデント設定

また、ESLintを導入するにあたり、コードのインデントを適切に設定しないと、大量のLintエラーに見舞われることになります。

airbnbのコーディングルールでは、インデント幅は(非タブ)スペース2個となっています。

今回は、以下のとおり~/.vimrcにインデント幅と、ES2015/JSX用の構文ツールの設定を追加しました(プラグインは設定のうえNeoBundleInstallで導入)。

set autoindent

augroup fileTypeIndent
  autocmd!
  autocmd BufNewFile,BufRead *.jsx setlocal tabstop=2 expandtab shiftwidth=2
  autocmd BufNewFile,BufRead *.json setlocal tabstop=2 expandtab shiftwidth=2
augroup END

NeoBundle 'pangloss/vim-javascript'
NeoBundle 'mxw/vim-jsx'

vim-jsxのES2015、JSX構文はよく対応できていて、ESLintのインデントエラーを一掃できたほか、ハイライトもきれいに表示されます。また、JSXのタグを複数行に分けて記述するケースにも適切に対応しています。

ESLintの位置づけ

ES2015を前提とすると、Babelなどのトランスパイラを経由してビルドすることになるのですが、webpackなどの周辺ツールを含めても構文エラーの検出はかなり弱い状況です。

ビルドツールだけで開発していると、Syntaxエラーも”Unexpected token”程度の情報しか出力されないため分かりづらく、かつビルドが通っても実行時エラーが頻発します。

コーディング段階のバグ早期発見のためには、Lintツールは必須と言えそうです。

また、じっさいにairbnbの設定をためしてみたところでは、とくに過激な文法を強いられるということもなく、妥当な範囲の警告が出力されている印象です。

中馬崇尋
Chuma Takahiro