YeomanでAngularJSしてCoffeeScriptにしてみた。っていうかGrunt最強って話
JavaScript FrameworkならBackboneでしょ。
と勝手に思い込んでそればっか使ってきたボクですが、年初にheavenshellとかどっぺちゃんとで飲んだ時にviewが重くなるよね―とか話してたしかにそれ悩みだよなと思った。
そんときAngularJSってどうなんだろうねーって話にちょっとなって、そんときからangularいつかやってみようと思いつつ仕事で忙殺されてたんだけど、今日何気にSNSで「AngularJSに仮入信してみる」ってつぶやいたらGoogleの人にいいね!してもらってちょっと上がった。
さらに都合のいいことに外出で2時間程度電車に乗ってヒマな時間ができたので、車中でAngularの洗礼を受けてみようとPCを開いた次第。ちなみに途中で酔いました。以前新幹線で思い知ったのだけど懲りてなかった。電車でコーディングは控えましょう。特に自分。
さて、AngularJS。Google製JavaScript Frameworkである。どんなものかというのはググればいいので省略するとして、ボクがangular気になってる点というのはDIパターンを採用している点。クラス間の依存性が疎になるほうがコード量が増えていってもテストしやすくなるんじゃね?と。
Backboneだと依存性強く書けちゃうので、メンテナンスしていくとどうしてもそうなって、特にViewにしわ寄せがいってテストとか書きづらくなる。まあ自分の実力不足もあるんだろうけど、そういう傾向あるねって年初の会でも話題になってた。まあそういうのをangularなら小マシになるかもなと期待してやってみるわけです。
まあいっぺん書いてみようと。angularはまったく知らないので本家のチュートリアル見ながらイチからです。しかし本家からzipをダウンロードはしない。最近は何をつくるにもyeomanから始めることになっているのでyeomanからangularのプロジェクトを作成する。
$ yeoman init angular
こっから勉強していくことにした。ちょいとチュートリアルとはファイル構成が違うけど、まあわかるからいいや。つーかyeoman便利。
yeomanが吐いてくれるJSは app/scripts/app.js と app/scripts/controllers/main.js。app.jsをルーターにしてcontrollers/以下にコントローラーを置いていく感じ。index.htmlではapp.js, main.jsの順に読み込んでる。OKこれをcoffeeに訳す。 app.coffeeとmain.coffeeはこんな感じにした。
あとはこのまま yeoman server で完成!と思ったらそうはいかない。他のframeworkよろしくangulerもオブジェクトを各クラス間で使いまわす。しかしCoffeeScriptはコンパイル時にデフォルトでファイルごとのソースを匿名関数でラッピング(即時関数っていうんだっけ?)する。
上記のソースの場合、app.coffeeで生成した angulerApp を main.coffeeで呼び出してcontrollerを登録しているのだけど、このままコンパイルすると出力されるapp.js と main.jsとでは名前空間が異なるので、main.jsでangulerAppなんてないよ、とエラーになるわけである。
coffeescriptで複数のファイルでアプリを書く、例えば1クラス1ファイルみたいにするとすごくキレイに書けるんだけど、コンパイル時に上記のようになるのでそのままじゃ動かない。こういうときどうするかというと、coffeeコマンドで --join オプションを使って各ファイルを結合したり、 --bare オプションで即時関数化を無効化して各ファイルをグローバルで動くようにする。どちらを選ぶかはケースによって判断するのがいい。
yeomanではcoffeeのコンパイルをGruntに一任している。Gruntのcoffeeプラグインをみてみると、bareオプションが使えるみたいなので、yeoman angulerではbareでコンパイルするのが効率良さそうだ。ということで、プロジェクト直下のGruntfile.jsを以下のようにする。
29〜32行目にoptionsブロックを追加し、bareをtrueに設定。これでcoffeeのコンパイル時にグローバルなjsを吐いてくれるようになる。これで yeoman serverを実行すると正常にアプリケーションが起動する。
実はボクはこのときまでGruntでbareオプションが設定できるのを知らなくて、今までGruntで複数ファイルを連結するときはconcatで連結してからコンパイルという設定をやってきた。こんなふうに。これはこれでアリなんだけど、ファイルが増えるたびにGruntfileを更新しないといけなくてもっといい方法ないかなーと思ってたら上記のようなカンタンな方法があったわけですね。ドキュメント読まな。。orz
まあ何はともあれyeoman angulerでも気持よくcoffeeで書けそうになったのでちょっとAngulerJSを勉強してみますわ―という本日からしばらくになりそうです。つーかいつも思うけどGrunt便利すぎ最強。