読者です 読者をやめる 読者になる 読者になる

hakobera's blog

技術メモ。たまに雑談

Connect ソースコードリーディング(1) - ソースコードの依存関係

前置き

Node.js で一番よく使われている Webフレームワークといえば、Express です。で、その Express が大きく依存しているのが Connect です。

Express を制するにはまずは Connect から、というわけで、Connect のソースコードを読み始めました。
対象とする Connect のバージョンは現時点(2011/11/23)での最新版である 1.8.1 (Express 2.5.1 が依存)です。

初回は、ソースを読む前の事前準備として、ソースコードの依存関係と各ソースの概要について説明します。

Connect ソースコードの場所

1.x ブランチ (master は 2.0.0alpha1 なので注意)
senchalabs/connect at 1.x · GitHub

現時点でのメイン・コミッター(≒ 最もアクティブにコミットしている人の意)は Express の作者である TJ Holowaychuk で、ライセンスは MIT ライセンスです。

ソースは以下のドキュメントで概要を掴んでから読むと理解しやすい。
Connect - High quality middleware for node.js

依存関係

ドキュメント以外の Connect リポジトリ内のソース/リソースの依存関係だけ洗い出すと以下のようになります。(標準モジュールやnpmモジュールへの依存関係は除いてあります)

index.js
 |- lib/connect.js
      |- lib/http.js
      |
      |- lib/https.js
      |    |- lib/http.js
      |
      |- lib/patch.js
      |
      |- lib/utils.js
      |
      |- middleware/basicAuth.js
      |     |- lib/utils.js
      |
      |- middleware/bodyParser.js
      |
      |- middleware/compress.js
      |
      |- middleware/cookieParser.js
      |     |- lib/utils.js
      |
      |- middleware/csrf.js
      |     |- lib/utils.js
      |
      |- middleware/directory.js
      |     |- lib/utils.js
      |     |- lib/public/style.css
      |     |- lib/public/directory.html
      |     |- lib/public/icons 配下のアイコン(PNG)ファイル
      |
      |- middleware/errorHandler.js
      |     |- lib/utils.js
      |     |- lib/public/style.css
      |     |- lib/public/error.html
      |
      |- middleware/favicon.js
      |     |- lib/utils.js
      |     |- lib/public/favicon.ico
      |
      |- middleware/header.js
      |
      |- middleware/limit.js
      |
      |- middleware/logger.js
      |
      |- middleware/methodOverride.js
      |
      |- middleware/profiler.js
      |
      |- middleware/query.js
      |
      |- middleware/responseTime.js
      |
      |- middleware/session.js
      |     |- middleware/session/session.js
      |     |- middleware/session/memory.js
      |     |- middleware/session/cookie.js
      |     |- middleware/session/store.js
      |     |- lib/utils.js
      |
      |- middleware/static.js
      |     |- lib/utils.js
      |
      |- middleware/staticCache.js
      |     |- lib/utils.js
      |     |- lib/cache.js
      |
      |- middleware/vhost.js

※ lib/index.js には実装はなく、ドキュメント用の jsdoc が書いてあるのみです。

各モジュールの概要

上記の依存関係を見ると分かる通り、Connect は少数のコアモジュールと middleware と呼ばれるプラグイン群で構成されています。middleware に関しては、後日別のエントリで解説するので、今回はコアモジュールのみ説明します。

ソース 概要
connect.js ブートストラップ。createServer 関数、コアモジュール(HTTPServer, HTTPSServer, utils) と 組込み middleware の export 及び patch 当て
http.js middleware をプラグインとして利用可能な HTTPServer の定義。HTTPServer は Node の 標準http モジュールの http.Server.prototype を継承し、use(), handler() メソッドを追加しています
https.js HTTPServer の SSL 対応版
utils.js ユーティリティ関数の定義。connect.utils 経由で呼び出せる。(詳細はドキュメント参照。後日エントリでいくつか解説します。)
cache.js staticCache ミドルウェアから利用されるメモリ内 LRU キャッシュクラス Cache の定義

コアモジュールだけ見ると、数も少なく、実装もとてもシンプルです。コアは小さくし、必要な機能をプラグインとして実装することで、柔軟なリクエスト処理を可能にしているのがわかります。

おまけ: patch.js って何やってるの?

jsdoc から自動生成されたドキュメントが微妙なので、おまけで解説しておきます。
Node.js の http.OutgoingMessage.prototype(= res) に以下のパッチをあてています。

  • res.hederSent() メソッドの追加
  • res.setHeader() メソッドで
    • Set-Cookie で複数クッキーを同時に設定できるようにする
    • Content-Type 指定時に自動的に '; charset=x' を追加する
  • res._renderHeader() 呼び出し時に 'header' イベントを emit する処理を追加

次回予告

次回は Connect の基本的なリクエスト処理の流れと middleware の概要を解説します。