Express読んだ
Node.jsのWebアプリケーションフレームワークexpressのソースコードを読んだ。
Node.jsの書き方とかHTTPの仕様とか調べながらコード読んで勉強になった。
読むときに作ったメモを載せておく。テキトーすぎてまったく参考にならないと思う。
依存モジュール
気になったものだけをメモ
connect
ミドルウェアを使って拡張できるHTTPサーバーフレームワーク
便利なmiddlewareが色々入ってる
commander
コマンドパーサーみたいなやつ
range-parser
HTTPヘッダフィールドのrangeをパースするやつ
小さくて読みやすそう
fresh
http response freshnessを調べる単純なやつ
キャッシュ制御につかう
methods
ただのhttp method 一覧
send
static() file server
面白そう
connectを読む
expressはルーティング等の機能がconnectのmiddlewareとして実装されていて、connectに大きく依存する形で作られている。
そのため、expressを理解しようとなるとまずconnectのコードを読んで理解しないといけない。
使用例はこんな感じ
var connect = require('connect') , http = require('http'); var app = connect() .use(connect.favicon()) .use(connect.logger('dev')) .use(connect.static('public')) .use(connect.directory('public')) .use(connect.cookieParser()) .use(connect.session({ secret: 'my secret here' })) .use(function(req, res){ res.end('Hello from Connect!\n'); }); http.createServer(app).listen(3000);
lib/connect.js
ここからはじまる。connect()で呼び出されるのはcreateServer
同梱されてるmiddlewareをロードする
lib/patch.js
http.serverResponseにメソッドを追加する
lib/proto.js
app.useを定義したり
メインっぽい
抽象クラスみたいな感じ
lib/connect.jsから呼び出される
app.use
よく使うやつ
ミドルウェアをstackに積む
middlewareはこんな感じの何かするやつ。nextを呼び出すと次のやつにいく
function(req, res, next) {}
app.handle
リクエストを処理する
stackを下から順に見ていき、routeにマッチしたら実行していく
nextを繰り返す
おもしろい
next
次のミドルウェアに進む
次に処理するものなくなったり、処理が終わったらエラーを出したりとかする
app.listen
http.createServer(app)してlistenするだけ
http.createServer
http.Serverオブジェクトを返す
http.ServerはEventEmitterでリクエストが来るたびに'request'イベントを発火させる
function (request, response) { }
コールバックにはhttp.ServerRequestとhttp.ServerResponseが引数として渡される
createServerには[requestListener]を渡すことができて、自動で登録してくれる
expressを読む
lib/express.js
createApplicationがexposeされてる
connectのミドルウェアをexpress.*として見えるようにしたり
createApplication
connectの上にapplication(lib/application.js)を重ねてinitする
lib/application.js
中心的な処理
app.defaultConfigulation
initが呼び出す
middlewareを設定したり
app.routerを設定したりとか
app.use
connect#use()へのproxy
別のapplicationをmountすることとかもできる
app.engine
引数の拡張子に対して使用するtemplate engineを登録する
中でやってるのはとりあえずプロパティに代入するだけ
app.set
settingに代入するのと、参照するの
app.getの実体もこれ
app.enable
app.setでtrueを代入するだけ
app.disable
app.setでfalseを代入するだけ
app.configure
development, stage, productionなど環境に応じた設定
app.render
template engineで描画する
view.renderを呼び出してる
res.renderで呼び出されたり
lib/router/index.js
Routerがexposeされてる
router.middlewareにmiddlewareが入っていてapplication.jsではこれを使ってる
map
method(getとかpostとか)をキー、Routeオブジェクトの配列を値としたハッシュ
_dispatch
middlewareの実体
requestにマッチするrouteを取り出し
paramを適用したりする
面白かった
param
paramに設定されたcallbackを順番に実効する
たとえば /users/:id で
app.param('id', function(req,res,next,val) { // hoge ….. })
だとこのコールバックに適切なパラメータを渡して実行する
paramのcallbackの実行が終わったら
routeのcallbackを順番に実行する
route
routeを定義する
app.getとかapp.postとかを扱うのはこれ
Routeオブジェクトを作ってRouter#mapに放りこむ
(this.map[method] = this.map[method] || []).push(route);
matchRequest
this.mapからrequestにマッチするrouteを探してきて返す
lib/middleware.js
X-Powered-Byをセットしたり
reqやresを初期化したりするmiddleware
lib/view.js
view.render(option, fn)
engineで描画する
lib/request.js
http.ServerRequestの拡張
lib/response.js
http.ServerResponse
地道な感じ