ExpressとWebSocketを使ったWebSocketのサンプルを作る準備

このエントリはリアルタイムWebハッカソンのハンズオン資料その2です。

前回の記事でnode.jsとnpmのインストールは完了しているものとします。

まずは必要なライブラリのインストール

$ npm install express jade less socket.io
npm info it worked if it ends with ok
npm info using npm@0.2.3-6
npm info fetch http://registry.npmjs.org/express/-/express@1.0.0rc4.tgz
npm info fetch http://registry.npmjs.org/less/-/less-1.0.36.tgz
npm info fetch http://registry.npmjs.org/socket.io/-/socket.io-0.5.3.tgz
npm info fetch http://registry.npmjs.org/jade/-/jade@0.5.3.tgz
npm info install express@1.0.0rc4
npm info install socket.io@0.5.3
npm info install less@1.0.36
npm info install jade@0.5.3
npm info activate socket.io@0.5.3
npm info activate less@1.0.36
npm info activate jade@0.5.3
npm info activate express@1.0.0rc4
npm info build Success: socket.io@0.5.3
npm info build Success: less@1.0.36
npm info build Success: jade@0.5.3
npm info build Success: express@1.0.0rc4
npm ok

ExpressはSinatraライクなnode.jsのWebアプリケーションフレームワーク
JadeHamlライクなnode.jsのテンプレートエンジンでlessCSS拡張lessのnode.js版。両方ともExpressが標準でサポートしている。
Expressがサポートしているテンプレートエンジンは他にもEJSHamlCoffeeKupがあり、CSS拡張もsassnode.js実装をサポートしてる。でまあ、好きなの使えばいいんだけど後述のジェネレータで作られたアプリでデフォルトで使われてるのがjadeとlessなので、ここではjadeとlessを使うことにする。

で、おもむろに以下を実行する

$ express sample
   create : sample
   create : sample/app.js
   create : sample/public/javascripts
   create : sample/logs
   create : sample/pids
   create : sample/public/images
   create : sample/public/stylesheets
   create : sample/public/stylesheets/style.less
   create : sample/test
   create : sample/test/app.test.js
   create : sample/views/partials
   create : sample/views/layout.jade
   create : sample/views/index.jade

すると、必要なファイルとディレクトリが作られアプリ基盤が完成する。
publicが静的ファイル置き場。(クライアントサイドの)JavaScriptCSSや画像なんかはここに置く。viewsはテンプレートファイル置き場。静的なHTMLならpublicに置けばいいんじゃないかな。testはテストコード置き場。logsはログファイルが作られる場所。pidsは複数プロセス立ち上げた時の管理用…だと思う。(ぶっちゃけ前まではpublicとviewsしかなくて、このエントリ書くために今実行してみたらその他のが出来てたので戸惑ってるところ)。
この状態ですでに実行可能になっているので実行してみます。

$ cd sample
$ node app.js
Express server listening on port 3000

ブラウザでlocalhost:3000にアクセスし、Welcome to Expressと表示されたら成功。

app.jsの中身はこんな感じ。

/**
 * Module dependencies.
 */

var express = require('express');

var app = module.exports = express.createServer();

// Configuration

app.configure(function(){
  app.set('views', __dirname + '/views');
  app.use(express.bodyDecoder());
  app.use(express.methodOverride());
  app.use(express.compiler({ src: __dirname + '/public', enable: ['less'] }));
  app.use(app.router);
  app.use(express.staticProvider(__dirname + '/public'));
});

app.configure('development', function(){
  app.use(express.errorHandler({ dumpExceptions: true, showStack: true })); 
});

app.configure('production', function(){
  app.use(express.errorHandler()); 
});

// Routes

app.get('/', function(req, res){
  res.render('index.jade', {
    locals: {
        title: 'Express'
    }
  });
});

// Only listen on $ node app.js

if (!module.parent) {
  app.listen(3000);
  console.log("Express server listening on port %d", app.address().port)
}

まあ、見たら大体分かると思うけどちょっと補足。

  • 16行目でCSS拡張としてlessを使うことを指定している。
  • 21,25行目でdevelopmentモードのときとproductionモードのときのエラー処理を設定している。基本はdevelopmentモードなんだけど、以下のようにNODE_ENVにproductionを指定して動かせばproductionモードになる。
$ NODE_ENV=production node app.js
  • 31行目で'/'以下にアクセスされたときの動作を設定している。見てのとおりjadeのテンプレートファイルのindex.jadeを変数titleに'Express'を束縛して描画する。テンプレートファイルの拡張子を見てどのエンジンを使うかを自動的に判断するので複数のテンプレートエンジンを共存させることも可能。だけどまあ1つのエンジンしか使わないなら、12行目のconfigureの中で次のように指定してやって拡張子を省略することもできる。
app.set('view engine', 'jade');