CoffeeScriptでNode.jsアプリを書いてみる
すでにCoffeeScriptについてはいろいろ調べていて、
書いてみたりしたこともあったのですが、
Node.js自体はほぼノータッチでした
いろいろすばらしいことはわかっていたものの、
なかなか触る機会がなくて・・・(´-ω-)
皆さんご存じだと思いますが、
「Node.js」は話題のサーバサイドJSの一つです
ちょうど同時期に二大雑誌が特集してます
- 作者: 柏木泰幸,松野紘明,林聖高,杉義宏,飯塚直,高橋征義,徳永拓之,Tehu(張惺),中島聡,おにたま
- 出版社/メーカー: 技術評論社
- 発売日: 2011/08/24
- メディア: 大型本
- 購入: 17人 クリック: 714回
- この商品を含むブログ (16件) を見る
Software Design (ソフトウェア デザイン) 2011年 09月号 [雑誌]
- 出版社/メーカー: 技術評論社
- 発売日: 2011/08/18
- メディア: 雑誌
- 購入: 1人 クリック: 186回
- この商品を含むブログ (10件) を見る
先日、いくつかの偶然*1が重なり、
Node.jsを書いてみよう、ということになったのですが、
やっぱりJavaScriptは書きたくないよね・・・と
というわけで、以下のことを確認してみることに
- CoffeeScriptだけでNode.jsのコードが全て書けるか?
- CoffeeScriptはNode.jsで動くのだから、当然のはずだけど、一応
- モジュールによる構造化が可能か?
- 一つにファイルに全部のモジュールを書くとか効率が悪すぎる
- フレームワークの完成度
- 具体的にはExpress
- もちろん、全部CoffeeScriptで書けることが前提
- 外部ライブラリの存在
- memcachedやMySQLのような、サーバサイドの欠かせないもの
これが全部クリアになれば、「一般的な開発」ができるはず・・・というわけです
Node.jsのインストール
すでにCoffeeScriptを使っていたので、インストール済みではあったのですが、
改めて調べてみることに
元々はMacのHomeBrewでNode.jsを入れてました
brew install node
これでもいいのですが、アップデートが頻繁な技術なので、
rvmのようなバージョン管理がいるだろう、ということで、
「nave」を使ってみました
naveでNode.jsのバージョン管理&イベントループ詳説(1/3)- @IT
この記事の通りにインストールしまして、「nave use latest」をしたところ、
改めてbashのシェルを起動する動作になっており、
profileが適用されなかったので、「nave usemain latest」にしてます
・・・それだと結局、Homebrew経由と変わらんのですが(´・ω・`)
npmのインストール
npmというのはNode.jsのパッケージマネージャーです
RubyのgemとかPerlのCPANのようなあれです
これもインストール済みだったのですが、改めてインストール
curl http://npmjs.org/install.sh | sh
最近はこのタイプのインストーラーが多いですね
CoffeeScriptとExpressのインストール
npmからインストールだけ・・・なのですが、
以下の二つは全く違う意味になります
npm install express npm install -g express
前者はカレントディレクトリのライブラリとして、
後者はグローバルなライブラリとしてインストールされます
具体的には、前者は「./node_modules/express」に一式が、
後者は「/usr/local/lib/node_modules」にライブラリ本体、
「/usr/local/bin」にコマンドが入ります
CoffeeScriptはグローバルに使いたいので・・・
npm install -g coffee-script npm install -g express
・・・が正解です
Expressもいったんグローバルに入れておきましょう
Expressが吐き出すコードを眺めてみる
Rails同様、Expressもコマンドにより、
基本的なひな形を生成することができます
express exsample # ひな形一式を生成 cd exsample npm install # Rubyの "bundle install" に相当 node app.js # localhost:3000でサーバ起動
まず、「express」コマンドが「rails new」に相当します
引数なしの場合はカレントディレクトリに一式を生成します
次の「npm install」が「bundle install」に相当しますが、
bundleの「Gemfile」のように「package.json」というファイルで、
アプリで使うライブラリが定義されています*2
インストール先はカレントディレクトリの「node_modules」で、
Node.jsがライブラリを探す際、ここを探しにいく仕組みになってます
たいしたコード量ではないので、このひな形をざっと眺めるだけで、
だいたいの構造は見えてくるのですが、
今回の目的はあくまで「CoffeeScriptで書くこと」なので、このままでは使えません
CoffeeScriptでExpressのコードを書く
今回書いたコードはGitHubに置いてあるので、
そちらのhistroyを追ってもらった方が早いのですが、
大雑把にポイントだけ書いてみます
https://github.com/parrot-studio/nodejs-coffee-test
なお、CoffeeScript自体の文法にはノータッチでΣ(゚Д゚)ガーン
最小のコード
# app.coffee express = require 'express' app = express.createServer() app.get '/', (req, res) -> res.send 'Hello World!' app.listen 3000
この5行でサーバが起動し、「Hello Wolrd!」が表示されますΣ(・ω・ノ)ノ
- 「hoge = require 'piyo'」とすることで、hogeオブジェクトからpiyoモジュールが呼べる
- 「express.createServer()」がサーバの実体
- 「app.get [path]」でルーティング
- Sinatraに近いRESTfulな構造
- 「app.listen [port]」で待ち受ける
本質はこれだけです
外部クラスの呼び出し
ある程度の規模で開発をするのであれば、
クラスを外部から呼び出す・・・くらいのことがしたいです
そこで、それを実現する最小のコードを書いてみました
# comment.coffee class Comment constructor: (@name, @body) -> say: -> "#{@name} #{@body}" exports.Comment = Comment
express = require 'express' app = express.createServer() #util = require 'util' Comment = require('./comment').Comment com = new Comment 'Hello', 'World!' #console.log util.inspect com app.get '/', (req, res) -> res.send com.say() app.listen 3000
- 「exports」オブジェクトのプロパティとして、functionやクラスを公開する
- 逆にいえば、ファイル内で使われている他のfunctionはprivateになる、ということ
- 「require([file])」は、別ファイルのexportsオブジェクトを返す
- なので、Commentクラスは上記のコードで実体を取り出せる
- utilパッケージには便利な機能が
- Rubyの「Object#inspect」に該当するメソッドや、loggingの仕組みなど
その他の話
あとはもう、面倒なんでコードを見てくださいΣ(・ω・ノ)ノ
https://github.com/parrot-studio/nodejs-coffee-test
- 「memcache」モジュールを経由すればmemcachedとやり取りできる
- 「package.json」に追記して「npm install」
- 「JSON.parse」「JSON.stringify」を使えばオブジェクトも格納できる
- まあ、Rubyでも使っている手段だけど・・・
- memcachedとのやり取りは非同期なので注意
- もちろん、そこがNode.jsの肝
- 「jade」は仕様とExpressの吐くコードを見ればなんとなくわかる
- http://jade-lang.com/
- 他のテンプレートエンジンも使えるけど、これがデフォルトなので調べた
- 「app.configure」あたりは元のapp.jsからそのまま移植しただけなので、細かいとこ見てない
- 本格的にいじる時にでも調べ直す感じで・・・
- 「mysql」モジュールもあった
- 「memcache」と「mysql」でたいていのアプリはいけそうな・・・
コンパイルと実行
app.coffeeファイルを実行するだけなら、
coffeeコマンドでそのまま実行するだけです
coffee app.coffee
ただ、やはりコンパイルしてJSのコードに変換したいので、
アプリのルートで以下のコマンドを実行する方がベターです
coffee -b -o lib/ -c src/ #coffee -w -b -o lib/ -c src/
後者のように「-w」をつけると、ソースディレクトリを監視して、
更新されたファイルを自動コンパイルしてくれる・・・はずなのですが、
なぜか私の環境では動きませんでした(´・ω・`)
なので、手動で前者コマンドを叩きまくってましたが、
本気で開発するなら原因を突き止めたいところです
コンパイルさえできてしまえば、
「node lib/app.js」で起動できます
まとめ
- Node.jsを実際に書いてみるとなかなか面白い(`・ω・´) b
- Expressを使えばいろいろ作れそう
- 構造化の仕組みも整備されている
- ライブラリも思ったより多数
- やっぱりCoffeeScriptは楽
- Javascript特有の余計なことを考えなくていい
すぐにNode.jsで何か・・・というアイデアはないのですが、
RubyのコードであればCoffeeScriptでほぼそのまま書き直せるので、
何か移植してみると面白そうです
そうなると、「本番環境」特有の問題を考える必要がありますが、
それはまたいつか・・・