Expressを使うテンプレ覚書（最後にSocket.IO用のカスタマイズ一例を置いておく）


#目的
・Expressのテンプレがどのような構造、役割を果たしているのかをまとめておき、改造が必要な時などに思い出しやすくする。
 
・個人的な解釈です。くれぐれも過信しないでください。（間違っていたら意見を頂けると幸いです）

#環境
・node -v 5.4.1

#必要な予備知識（準備）
・NodeJS
・npmについて
・Expressのインストール（かつexpressコマンドが使えるようにパスを通す）

#Expressのテンプレの中身
	-app.js
	-bin
		-www
	-package.json
	-public
	-routes
	-views

##app.js
###どういうところか？
・URLリクエストを受け取り、修飾を施したのちに希望したディレクトリのページがあれば返し、なければerrを返す。

###処理内容
・基本上から

	１、モジュールの読み込み（必要な材料を揃える）
		・node_moduleの読み込み
		・routesフォルダにあるオリジナルjsファイル（モジュール）の読み込み
    	・自分で入れたjsファイル（モジュール）の読み込み
    ２、Expressインスタンスの作成。個人的に「モジュールはここまでだよ」という目印にしている。ここからExpressインスタンスを加工していく。（調理スタート）
    ３、レンダラーエンジンの指定（MVCの内、Vを指定する）
    ４、ミドルウェアの追加（nodeモジュール（材料）を組み込んで、Expressインスタンス自体は完成）
    ５、ルーティングの追加（配達先を指定しておく。）
    ６、エラー処理（配達先が見つからない場合、廃棄する）
    ７、最後にExpressインスタンスをエクスポート

という流れになる（と解釈）

###コードに当てはめると
```
//１、モジュールの読み込み
//node_module
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');

//オリジナルjsファイル
var routes = require('./routes/index');
var users = require('./routes/users');

//自分で入れる場合はここに

//２、Expressインスタンスの作成
var app = express();

//３、レンダラーエンジンの指定
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');

//４、ミドルウェアの追加
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

//５、ルーティングの追加
app.use('/', routes);
app.use('/users', users);

//６、エラー処理
app.use(function(req, res, next) {
  var err = new Error('Not Found');
  err.status = 404;
  next(err);
});

if (app.get('env') === 'development') {
  app.use(function(err, req, res, next) {
    res.status(err.status || 500);
    res.render('error', {
      message: err.message,
      error: err
    });
  });
}

// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
  res.status(err.status || 500);
  res.render('error', {
    message: err.message,
    error: {}
  });
});

//７、最後にExpressインスタンスをエクスポート
module.exports = app;
```

##www
###どういうところか？
・テンプレなら、一番最初に起動されるexecファイル。
・ポート番号の指定、サーバーの立ち上げ、サーバーのlistenを行っている

###処理内容
・基本上から

	１、appモジュールをrequireする
	２、debugモジュールをrequireする
	３、httpモジュールをrequireする
	４、port番号の宣言、appへのport番号のセット
	５、httpモジュールでappを引数にcreateServerし、server変数に格納
	６、serverをportへlistenさせる
	７、その他（エラー処理など）
という流れになる（と解釈）

###コードに当てはめると
```www
#!/usr/bin/env node

//１、appモジュールをrequireする
var app = require('../app');

//２、debugモジュールをrequireする
var debug = require('debug')('ReactServer:server');

//３、httpモジュールをrequireする
var http = require('http');

//４、port番号の宣言、appへのport番号のセット
var port = normalizePort(process.env.PORT || '3000');
app.set('port', port);

//５、httpモジュールでappを引数にcreateServerし、server変数に格納
var server = http.createServer(app);

//６、serverをportへlistenさせる
server.listen(port);
server.on('error', onError);
server.on('listening', onListening);

//７、その他（エラー処理など）
function normalizePort(val) {
  var port = parseInt(val, 10);

  if (isNaN(port)) {
    // named pipe
    return val;
  }

  if (port >= 0) {
    // port number
    return port;
  }

  return false;
}

function onError(error) {
  if (error.syscall !== 'listen') {
    throw error;
  }

  var bind = typeof port === 'string'
    ? 'Pipe ' + port
    : 'Port ' + port;

  // handle specific listen errors with friendly messages
  switch (error.code) {
    case 'EACCES':
      console.error(bind + ' requires elevated privileges');
      process.exit(1);
      break;
    case 'EADDRINUSE':
      console.error(bind + ' is already in use');
      process.exit(1);
      break;
    default:
      throw error;
  }
}

function onListening() {
  var addr = server.address();
  var bind = typeof addr === 'string'
    ? 'pipe ' + addr
    : 'port ' + addr.port;
  debug('Listening on ' + bind);
}
```

##routesファイル
###どういうところか？
・app.jsで振り分けられたあとの処理が詰まったモジュールが入っている
・基本的にはExpressのindex.jsのテンプレを真似ればいいが、役割がいくつか別れる

    ①URLを判定して、特定のページを表示させるもの。
    ②サーバー側で実行するビジネスモデルモジュール（SocketIOなど）
・両者とも、大まかには

	・必要なモジュールを読み込む
    ・関数、インスタンスを作成
    ・module.exportsでそれを送信
という流れになる。

##viewsファイル
###どういうところか？
・レンダーするひな型ファイルが入っている。
・デフォルトはjade。設定でejsにも変更可能

#カスタマイズの一例
・Socket.IOを使うようにカスタマイズしたものを一応あげておく

##app.js
```
//node_module（材料）
var express = require('express'),
    compression = require('compression'),
    path = require('path'),
    logger = require('morgan'),
    bodyParser = require('body-parser');

//オリジナルと自分で作ったモジュール
var routes = require('./routes/index'),
    PC = require('./routes/PC'),
    smartphone = require('./routes/smartphone');

//Expressインスタンス
var app = express();

//レンダラーエンジンの指定
app.set('views', path.join(__dirname,'views'));
app.set('view engine','jade');

//ミドルウェアの追加
app.use(compression());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(express.static(path.join(__dirname, 'public')));

//ルーティングの追加
app.use('/', routes);
app.use('/PC', PC);
app.use('/smartphone', smartphone);

//Expressインスタンスをエクスポート
module.exports = app;
```

##www
・Socket.IOの記述はものによっては結構長くなるので、別ファイルに書いておいたほうがすっきりする。

・しかし、Socket.IOの記述ができるのは、createServerしているところと同じファイルでないといけない。

・なのでcreateServerはこのファイルでは行わず、socketIO処理を書いておくモジュール(SocketIO.js)に記載したのち、このページへ読み込む形にする

```
#!/usr/bin/env node

//appモジュールをrequireする(ここではhttpモジュールは読み込まず、代わりにroutesフォルダに作ったsocket.IOを読み込む)
var app = require('../app');
var debug = require('debug')('ReactServer:server');
var socketIO = require('../routes/socketIO');

//port番号の指定
var port = normalizePort(process.env.PORT || '3000');
app.set('port', port);

//ソケットIOのモジュールを実行。（実はこの中でcreateServerしてlistenしている）
socketIO();

//以下はその他。変化なし

```

##SocketIO.js(routesファイル内に作成)
・ここでサーバーを立ち上げてlistenする処理も書く（createServerする）
・createServerをするにあたり、以下の三つが必要になることを覚えておくとやりやすい

	・app.jsモジュール
	・httpモジュール
	・ポート番号

```
//appモジュールを読み込む（このappには、www内ですでにポート番号が登録されているので、ポート番号を取得したことにもなる）
var app = require('../app');

//httpモジュールを読み込んで、サーバーを立ち上げる（createServerと同じ扱い）
var http = require('http');

//必要な三要素を揃えて初めてサーバーを立ち上げられる
var server = http.createServer(app);

//サーバーをlistenしてsocketIOを設定
var io = require('socket.io')(server);

//socketIOモジュール
function socketIO(){
	//サーバーを立ち上げたら実行
    server.listen(app.get('port'), function() {
        console.log('listening!!!');
    });

	//socket処理を記載する
    io.on('connection', function(socket){
    
        //socket処理
        socket.on('socketName',function(data){
            console.log(data);
            io.sockets.emit('socketName2',data);
        })
        
    });
};

//export
module.exports = socketIO;
```

・おしまい