jshintでjavascriptコードチェックしながら開発する

最近はjavascriptを書いています。
javascriptとしてはそれなりに大規模になってきました(2万行ぐらい?)。
最近のjavascriptトレンドのやり方は、コードチェッカを通して、信頼性を向上させるのがプロ技らしいです。
僕も早くプロの仲間に入りたいです。

コードチェッカには「JSLint」というのがあるらしいのですが、使ってみればわかりますが、さすがに警告が細かすぎてウザいです。
(「varは関数トップに一つ」とか特に。C言語じゃないんだから・・・。)
そういった部分をある程度柔軟にしたものに「JSHint」というのがあるみたいです。「JSLint」のフォークらしいです。

あまりに堅いスタイルを強要されたくなかったので、僕はこれを使ってみました。

そのまま使えるわけじゃないのでやったことをメモっておきます。

1.JSHintをダウンロードしてくる

http://jshint.com/
左上にDownloadがあるのでそこをクリックして開発マシンにダウンロードします。
jsを開発しているディレクトリに任意のディレクトリを掘ってそこにおいておくと良いでしょう。

2.node.jsインストール

JSHintはただのjsファイルなので、そのままだとブラウザ以外では実行できません。処理系が必要です。
js処理系であれば大体何でも動くと思いますが、
node.jsというのが最近流行ってるみたいなんでそれにします。

# linux Debian
$ sudo apt-get install nodejs
# FreeBSD
$ cd /usr/ports/www/node
$ configure
$ make
$ sudo make install

3.loader.js書く

JSHintそのままですと、javascript文字列を読んでチェックする機能しかありませんので、開発向けじゃありません。
loader.jsというのを作って、ファイルを指定してチェックしてくれるようにしたいと思います。

// loader.js
(function (global) {
  "use strict";

  var fs = require('fs'),
  jshint = require('./jshint.js');

  if (jshint) {
    jshint = jshint.JSHINT;
  } else {
    throw new Error('jshint is not found.');
  }

  var jshint_file = function (file) {
    fs.readFile(file, function (err, data) {
      if (err) throw err;
      var option = {
        browser: true,
        devel:   true,
        debug:   true
      },
      result = jshint(data.toString('utf-8'), option);

      if (!result) {
        jshint.errors.forEach(function (e) {
          if (e) console.log("WORNING!! file: " + file + " line: " + e.line +
                             " character: " + e.character + "\n\t" + e.reason + "\n");
        });
      }

    });
  };

  function main() {

    if (process.argv.length < 3) {
       // No files given. Nothing to do.
      return;
    }

    var files = process.argv.slice(2);

    files.forEach(function(file) {
      jshint_file(file);
    });

  };

  main();

})(this);

これをjshint.jsと同じフォルダに置いて、実行してみます。

# nodeもしくはnodejs(aptでインストールした場合)
# 引数のファイルはいくつでもつなげられる。

$ node loader.js loader.js

-> WORNING!! file: tools/loader.js line: 49 character: 4
           Unnecessary semicolon. # main();の前の行のセミコロンが不要。

うまく動いているようです。

4.実行スクリプトを書く

同じフォルダにcheckerスクリプトを作ります。

#!/usr/local/bin/bash

script_dir=`dirname $0`
target_dir=`pwd`

arg=$*
parg=()
count=0

for item in $arg; do
    parg[$count]=$target_dir"/"$item
    let count=$count+1
done

node $script_dir/loader.js ${parg[@]}

これで違うディレクトリにあるファイルでも

$ tools/checker development.js development2.js development3.js

とかできるようになりました。

5.Makefileを書く

MYSRCS  = \
        development1.js                \
        development2.js                \
        development3.js

.PHONY: all

all:    check comp

check:  $(MYSRCS)
        ./tools/checker $(MYSRCS)

comp:   $(MYSRCS)
        # ソースを結合し、圧縮する。

doc:    $(MYSRCS)
        # コメントからドキュメントを作成。

clean:
        rm main.cmp.js

とかでしょうか。
これでjsが書きあがった後、

$ make check

とすれば、ソースをチェックします。

doc(ドキュメント生成)とかcomp(圧縮)とかありますが、私はこんな風にやっています。
これらはまた時間があれば書こうと思います。

では。