ブラウザをターゲットとする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