俺は!WebStorm(5.0.2)でCoffeeScriptを!自動ビルドしたいんだッ!!

    こんばんわ、加藤です。

    最近ちょっとしたツール類とかMBPのローカルでNodejsで書くようになりました。
    なによりJavascriptって言語が一番慣れてますし、昔リリースされたばかりの頃に触ってみていたことがあるんですが当時に比べてかなり色々なパッケージが揃っているし、トータルスピードが早いですね。

    ところで、JSを書く際に「CoffeeScript最高!」という声はよく聞いていたんですけど恥ずかしながら・・・ちゃんとやってなかったのでCoffeeScriptを最近導入してみました。
    いやーこれはいいですねー楽ですねー書き捨てコード書くには最高です。

    そこで普段JSを書くのに使っているIDE、WebStormでCoffeeScriptを保存したらその場で自動的に.jsを吐き出すように設定してみました。
    そのときのメモです。
    coffeescriptでnodejs上で実行するJSのコマンドラインツールをつくってみましょう。

    とりあえずMac上に環境整えましょう。僕の環境はMac OSX MountainLionです。
    流れとしてはhomebrew入れる→homebrewでNode.js入れる→npmでCoffeeScript入れる。終わり です。
    え、Macports使ってるの?この際homebrewにしましょう!

    スクリーンショット 2013-03-04 15.40.01

    1.JAVA入ってるか確認

    ターミナルで

    java -version

    してください。javaが入っていない場合は入れてください

    2.XCode Command Line Toolsを入れる

    Xcode Command Line Toolsが入っていなければ入れる必要があるみたいです。僕は入ってました。
    これらは他の開発環境作るにもほぼ必須な物達なので面倒臭がらずに入れちゃったほうがよいです。
    Xcodeを起動して、Preferences >DownloadsからCommand Line Toolsをインストールできます。多分。

    3.homebrew(OSXのパッケージマネージャ)を入れる

    下記コマンドをターミナルから打ち込むとhomebrewが入ります。
    portsが有名でしたが現在はhomebrewのほうがよく使われています。既存パッケージへの配慮などされていてportsより安心です。

    ruby <(curl -fsSk https://raw.github.com/mxcl/homebrew/go)

    4.homebrewをアップデート

    brew update

    5.Nodejsを入れる

    brew install node

    yes!yes!

    6.npm(Nodeのパッケージマネージャ)を入れる

    curl https://npmjs.org/install.sh | sudo sh

    curlコマンドでsh落としてきて実行ですね。

    7.一応確認

    npm --version

    インストールやこれでエラーが出た場合はエラーメッセージをコピーしてGoogleだ!

    8.npmでCoffeeScriptをインストール

    sudo npm install coffee-script

    9.ここまでの環境を確認

    環境作りは以上です。とりあえずCoffeeScriotの環境が動いてるか試してみましょう。
    パスが通ってないとかそういう問題発生したら適宜対応しましょう。大概はエラーメッセージをGoogleに入れると答えが出てきます!!

    $ vi helloworld.coffee

    でとりあえずcoffeescript書いてみる

    helloworld = () ->
         console.log "hello world!!!!!!!!!!!!!!!!!!!!!"
    
    helloworld()

    :wq で閉じまして以下実行

    coffee helloworld.coffee

    こんなのがターミナルに表示されればOK!

    hello world!!!!!!!!!!!!!!!!!!!!!

    10.WebStormの設定をする

    準備が整いました。ここからが本番です。WebStormに設定をしましょう。
    ちなみに最新版のWebStormではCoffeeScript対応が既にされているのでプラグインなどを入れる必要はありません!便利!フューチャー!!!

    ここからはスクリーンショットを交えて解説しましょう

    10-1.WebStormで新規プロジェクトを作る

    スクリーンショット 2013-03-04 16.01.55
    プロジェクト名は適当に。今回は「XMLPerseTest」としてみました。
    プロジェクトタイプはEmptyProjectでいいと思います。

    10-2.ディレクトリ構成を作る

    スクリーンショット 2013-03-04 16.04.16
    とりあえず僕はこんな感じです。だいたいこの構成が自分の中で固まってきたらcoffeescript用とかでテンプレートにしておいていいと思います。

    root/
      .src/
        XMLPerseTest.coffee
      htdocs/
        js/

    要するにcoffeescriptをルートの.srcディレクトリに置いておいて、htdocs以下のjsディレクトリにjsファイルを吐き出してやろうという魂胆が丸見えです。
    今回はまぁ、コマンドラインで実行するNode用なのでhtdocsいらないんですけど勢いで作っちゃったのでこのまま行きましょう!

    10-3.保存設定

    スクリーンショット 2013-03-04 17.26.18
    XMLPerseTest.coffeeを右クリックなりなんなりして[Create ‘XMLPerseTest.coffee…]を選択するとこのような設定画面が表示されるのでスクリーンショットと同じように設定してください

    Enviroment Variables: PATH=/usr/local/bin
    →/usr/local/binにパスを通す

    Path to coffee executable: /usr/local/bin/coffee
    →coffee scriptへのパス

    coffescript parameters: オプションを指定します
    -c…コンパイル
    -w…ソースが更新されたらすぐに再コンパイルする
    -o… JSファイルを出力するディレクトリを指定

    -c -w -o ../htdocs/js

    以上です。では実際にcoffeescriptをXMLPerseTest.coffeeに記述してビルドできるかテストしてみましょう

    10-4. ビルドしてみる

    console.log "helloworld!!!!!"

    とか、テストコードを適当に書いたら上にある再生ボタンみたいなボタンを押してみましょう
    Runです。Runします!!
    下のコンソール部分になにやらうまく行ったとか失敗したとかメッセージが出るので見てみましょう
    成功するとスクリーンショットのようにjsディレクトリにJSファイルが生成されています。

    11.CoffeeScriptでテストコード書いてみる

    適当にcoffeescriptを書いてみましょう
    ここではvitalify.jp上のブログのRSSを取得して最新記事のタイトルを表示してみます。

    とりあえずhttp通信を行うライブラリの”http”とjQueryライクにXMLパースする軽量の”Cheerio”を使ってみます。
    新しいパッケージをnodeに入れるにはターミナルから

    sudo npm install http
    sudo npm install cheerio

    で入ると思います。

    http = require 'http'
    cheerio = require 'cheerio'
    
    xml_host = 'vitalify.jp'
    xml_path = '/blog/category/news/feed'
    
    getXML = (xml_host, xml_path) ->
      http.get
        host: xml_host
        path: xml_path
      ,(res) ->
        if res.statusCode is 200
          body = ''
          res.setEncoding 'utf8'
          res.on 'data', (chunk) ->
            body += chunk
          res.on 'end', ->
            getLatestTitle body
        else
          console.log "error: #{res.statusCode}"
    
    getLatestTitle = (xml) ->
      $ = cheerio.load(xml,{
        ignoreWhitespace: true
        xmlMode: true
      })
      $entries = $('item')
      $entry = $entries.eq 0
      $title = $entry.children "title"
      console.log $title.text()
    
    getXML xml_host, xml_path

    Javascript書いたことがあればだいたい分かると思いますがhttpでXML取得 cheerioでXMLをパースしてますね。
    上記コピペし、五感を研ぎ澄ましながらCmd+sを押しますと自動的にJSファイルが更新される手応えを感じると思います。

    試してみましょう

    ターミナルでJSを保存したディレクトリへ移動し、nodeで実行!!
    スクリーンショット 2013-03-04 16.54.41

    $ cd ~/Docs/workspace/XMLPerseTest/htdocs/js
    $ node XMLPerseTest.js
    雑誌「日経コンピュータ2013年2月7日号」にてバイタリフィのオフショア開発実績が紹介されました。
    $

    やったー!

    ちなみにこんなJSが吐き出されてました。

    // Generated by CoffeeScript 1.4.0
    (function() {
      var cheerio, getLatestTitle, getXML, http, xml_host, xml_path;
    
      http = require('http');
    
      cheerio = require('cheerio');
    
      xml_host = 'vitalify.jp';
    
      xml_path = '/blog/category/news/feed';
    
      getXML = function(xml_host, xml_path) {
        return http.get({
          host: xml_host,
          path: xml_path
        }, function(res) {
          var body;
          if (res.statusCode === 200) {
            body = '';
            res.setEncoding('utf8');
            res.on('data', function(chunk) {
              return body += chunk;
            });
            return res.on('end', function() {
              return getLatestTitle(body);
            });
          } else {
            return console.log("error: " + res.statusCode);
          }
        });
      };
    
      getLatestTitle = function(xml) {
        var $, $entries, $entry, $title;
        $ = cheerio.load(xml, {
          ignoreWhitespace: true,
          xmlMode: true
        });
        $entries = $('item');
        $entry = $entries.eq(0);
        $title = $entry.children("title");
        return console.log($title.text());
      };
    
      getXML(xml_host, xml_path);
    
    }).call(this);