PureScript開発に至る前の環境整備

## 経緯
* bacon.jsのbindingを書こうと思った
* よく考えたら僕の知ってるjsの知識は化石クラスに昔のものだった
* node.jsは名前は知ってるけどnpm? bower? grunt? gulp?なにそれ美味しいの？状態
* 備忘録兼ねてのメモ

## node.jsの導入

node.js自体はサーバサイドjsの処理系なんだけど、jsをプロセス立ち上げて使う系全般の処理系になってるっぽい。で、フロントエンドjsの開発にもjsで作られたコマンドをバンバン使うので必要らしい。

```console
$ # Ubuntu
$ # nodebrewで入れた see http://qiita.com/sinmetal/items/154e81823f386279b33c
$ # Mac
$ brew install node
```

Ubuntuでnodebrewで入れた理由は、Ubuntuでaptで入れたものと後で出てくる`npm install -g`みたいな`/usr`以下にものをインストールするコマンドの相性が最悪だと予想されるから。Homebrewの方は深く考えてないだけでこっちもnodebrewのほうがいいかもしれない。

## bowerを入れる
bowerってのはフロントエンドjsのパッケージマネージャで、将来みんながpurescript-baconを使おうと思ったらこのbowerのパッケージが使えないとダメらしい。なので、そのコマンドをインストール。

```console
$ npm i -g bower
```

## テンプレ程度のパッケージを用意
役者はとりあえず揃ったので、自分の作るソフトに対して2つのパッケージを定義してやる。1つはnpmのパッケージ。node.jsのパッケージなんでフロントエンドjsに必要ないだろって思うんだけど、後でビルドツールを使うために必要らしい。なので公開するとかはない。適当でいい。bowerの方はみんなに使ってもらうほうなので必要。

```console
$ npm init
$ # いろいろ答える、適当でいいよ
$ bower init
$ # いろいろ答える、ちょっとは真面目に答えてね
```

これでpackage.jsonってのとbower.jsonってのができる。`bower init`するときにどのモジュールタイプにする？みたいなこと聞かれるけど適当でいいらしい。

## gulpの導入
jsも最近はモジュールがどうとか、そもそもaltJSってコンパイルしないとダメだよね、とかminifyしたいとかいろいろな理由から結局make的なものまで必要になったらしい。Makefileではなく、gruntというのとgulpというのが主に使われてるっぽいけどGruntはあまりにまどろっこしかったので勉強するのをやめてgulpを使うことにした。

```console
$ npm i -g gulp
$ npm i --save-dev gulp gulp-purescript 
```

gulpを`-g`付きでコマンド入れておくだけではダメで、`-g`なしでローカルにもインストールしないとダメ。ちなみに、`--save-dev`ってのはさっき作ったpackage.jsonの依存するパッケージ欄に勝手に追記しておいてくれるオプション。

この辺でjs的なところの準備は終わってPureScript固有の話になってくるかな。

## PureScriptコンパイラの導入
cabal-installの導入とかは省くからごめん。cabalでさくっと入れる。sandbox使っとかないと爆死するのでわからなかったらこうするかバイナリダウンロードしていれたほうがいい。

```console
user@~$ # 最新が0.6.2だった
user@~$ LATEST=0.6.2
user@~$ mkdir -p ~/cabal-sandbox/purescript/$LATEST
user@~$ cd ~/cabal-sandbox/purescript/$LATEST
user@~/cabal-sandbox/purescript/w.x.y.z$ cabal sandbox init --sandbox=`pwd`
user@~/cabal-sandbox/purescript/w.x.y.z$ cabal install -j purescript
user@~/cabal-sandbox/purescript/w.x.y.z$ cd ~/cabal-sandbox/purescript/
user@~/cabal-sandbox/purescript$ ln -s $LATEST current
user@~/cabal-sandbox/purescript$ ln -s current default
user@~$ # あとは$PATHの通ったところにコマンドをリンクしておく、例えば
user@~/local/bin% for i in ~/cabal-sandbox/purescript/default/bin/*; do ln -s $i; done
```

## gulpfile.jsの用意
さっき言ってたとおりgulpってのはmakeみたいなものなのでMakefileに相当するものも必要。それが、gulpfile.jsだ。

```shell-session
user@/path/to/project% gulp
[22:40:55] No gulpfile found
user@/path/to/project% emacs gulpfile.js
```

```js:gulpfile.js
var gulp = require('gulp');
var purescript = require('gulp-purescript');
var del = require('del');

var paths = {
  purescripts: ['src/**/*.purs', 'bower_components/**/src/**/*.purs']
};

gulp.task('clean', function(cb) {
  del(['build'], cb);
});

gulp.task('purescript', function() {
  return (
    gulp.src(paths.purescripts)
      .pipe(purescript.psc({noPrelude: true}))
      .pipe(gulp.dest('build/'))
  );
});

gulp.task('default', ['purescript']);
```

```shell-session
user@/path/to/project% gulp
[22:59:21] Using gulpfile /path/to/project/gulpfile.js
[22:59:21] Starting 'purescript'...
[22:59:21] Finished 'purescript' after 23 ms
[22:59:21] Starting 'default'...
[22:59:21] Finished 'default' after 12 μs
user@/path/to/project% gulp clean
module.js:338
    throw err;
          ^
Error: Cannot find module 'del'
    at Function.Module._resolveFilename (module.js:336:15)
    at Function.Module._load (module.js:278:25)
    at Module.require (module.js:365:17)
    at require (module.js:384:17)
    at Object.<anonymous> (/path/to/project/gulpfile.js:3:11)
    at Module._compile (module.js:460:26)
    at Object.Module._extensions..js (module.js:478:10)
    at Module.load (module.js:355:32)
    at Function.Module._load (module.js:310:12)
    at Module.require (module.js:365:17)
    at require (module.js:384:17)
    at Liftoff.handleArguments (/home/user/.nodebrew/node/v0.11.14/lib/node_modules/gulp/bin/gulp.js:116:3)
user@/path/to/project% npm install --save-dev del
del@1.0.0 node_modules/del
├── is-path-cwd@1.0.0
├── rimraf@2.2.8
├── each-async@1.1.0 (onetime@1.0.0, setimmediate@1.0.2)
├── is-path-in-cwd@1.0.0 (is-path-inside@1.0.0)
└── globby@1.0.0 (array-differ@1.0.0, async@0.9.0, array-union@1.0.1, glob@4.3.1)
user@/path/to/project% gulp clean
[23:00:11] Using gulpfile /path/to/project/gulpfile.js
[23:00:11] Starting 'clean'...
[23:00:11] Finished 'clean' after 5.26 ms
```

だいたいこれでおしまい！