October 2015

Volume 30 Number 10

働くプログラマ - MEAN あれこれ: Express のインストール

Ted Neward | October 2015

MongoDB、Express、AngularJS、Node.js (MEAN) スタックは、.NET 開発者にはおなじみの ASP.NET スタックに代わる "Web スタック" です。このスタックは、補完的とか、補足的といわれることもあります。シリーズ 3 回目となる今回は、サーバーで HTTP を処理する Express ライブラリを取り上げます。

前回 (msdn.microsoft.com/magazine/mt422588、英語) は、Node.js アプリケーションを Microsoft Azure にインストールする方法を紹介しました。この操作は、事実上、Git リポジトリにコミットする (その後そのコミットを Azure リモート リポジトリにプッシュする) だけです。そのため、少なくとも Azure プラットフォームで他のサービス (MongoDB など) を使うことになるまでは、この話題を取り上げる予定はありません。ただし、ローカル コンピューターですべての例を実行すれば、同じことが可能です。必ずしも Azure は必要ありません (運用環境にプッシュする部分は例外です)。

Express について

Express は非常にわかりやすいライブラリで、「Node.js のしくみ」がわかれば、操作は簡単です。わかりやすいように、(ある程度) 初歩的なところから始めます。「azure site create --git」コマンドが成功した結果として作成される新しい Azure サイトと、シンプルな Express アプリケーションが稼働していることが今回の前提です。

シリーズ初回 (msdn.microsoft.com/magazine/mt185576) では、Node パッケージ マネージャー (npm) を取り上げました。npm は、すべての Node アプリケーションにとって、ライブラリと依存関係マネージャーの役割を果たします。これは、Microsoft .NET Framework 環境での NuGet の役割に似ています。実際、どちらも Ruby gem の影響を受けているため、多くの共通点があります。

結局のところ、npm はすべての情報を 1 つの JSON ファイル (package.json) に依存しています。このファイルは、すべての依存関係 (運用パッケージと開発専用のパッケージ) を保持します。したがって、Express を使用して依存関係としてこのファイルを作成するのが、理論上最初の手順です (図 1 参照)。

図 1 Express を使用して依存関係としてファイルを作成

{
  "name": "MSDN-MEAN",
  "version": "0.0.1",
  "description": "Testing out building a MEAN app from scratch",
  "main": "app.js",
  "scripts": {},
  "author": "Ted Neward",
  "license": "ISC",
  "dependencies": {
    "express": "^4.9.8",
    "lodash": "^2.4.1",
    "serve-static": "^1.7.0"
  },
  "devDependencies": {
  }
}

このファイルの内容はほぼ一目瞭然ですが、特筆すべき項目がいくつかあります。まず、このファイルは、手動で管理するのがほとんどです (ただし、管理を目的とするツールもいくつかあります)。これは、Node.js 環境での「テキスト エディターとコマンド ライン」の関係と同じです。したがって、Node 開発者志望の方なら、ツールがなくても難なく手動で編集できるはずです。さて、ここには 2 つの依存関係があります。1 つは dependencies 項目で、運用タイプの環境に npm がインストールするパッケージを表します。もう 1 つは devDependencies 項目で、開発者だけが使用するパッケージを表します。

今のところ、dependencies はアプリが (Git を通じて) Azure にプッシュされるときにインストールされると考えるのが最も簡単です。(dependencies のコンテンツと共に) devDependencies がインストールされるのは、開発者の PC にパッケージをインストールするときです (図 2 参照)。

依存関係のインストール
図 2 依存関係のインストール

それでは、インストールを実行しましょう。カレント ディレクトリに package.json ファイルだけを用意して、コマンド ラインで「npm install」と入力すると、npm がローカル コンピューターに express、lodash、serve-static を取り出します。lodash は、マップやフィルターのような実用的なツールや、配列とオブジェクトの拡張機能を含む、関数とメソッドの便利なライブラリです。serve-static については後ほど説明します。

NuGet と同様に、npm はパッケージだけでなく依存関係もすべてインストールします。これは、端末にツリー表示されます。一般的なパッケージを多数内包している包括的なパッケージでは、ツリー表示が非常に長くなります。ここでは package.json から 2 つのエントリ (このパッケージが元あった repository フィールドと README データ) が除外されていることが npm ツールによって指摘されています。この 2 つは、npm の中央ライブラリにインストールされる npm パッケージに対して主に使用されます。これらがアプリケーションに特に適しているとは思いませんが、npm から警告が表示されることを望まないのであれば、保持していてもまったく害はありません。

このシリーズでは今後、package.json に他のパッケージを追加する予定です。そのため、新しいパッケージを取得するために npm install を定期的に実行することになるでしょう。実のところ、Express の install 出力ツリーでは、(前回のコラムで使用した) debug パッケージが依存関係として示されるはずですが、今回はこのパッケージを直接 package.json ファイルに配置しませんでした。シリーズでは、直接使用するすべての dependencies を明示的に package.json ファイルにリストしているため、次のように、dependencies を package.json に追加してもう一度 npm install を実行します (その結果、ライブラリが使用しても、直接呼び出すことは決してない dependencies が区別されます)。

"dependencies": {
  "debug": "^2.2.0",
  "express": "^4.9.8",
  "lodash": "^2.4.1",
  "serve-static": "^1.7.0"
},

こうすれば、デバッグ環境と運用環境の違いが重要になる場合、(Express が使用しているバージョンとは異なり) 実際に使用している debug バージョンがわかりやすくなります。ちなみに、ライブラリ (ファイル形式は説明済み) の標準インストール方法は、「npm install <パッケージ> --save」です。"--save" 引数を使用すると、npm が package.json ファイルを変更します (これは、記録を行わずにインストールするのとは対照的です)。

事実、「npm install express --save」を実行すると、express エントリが既に存在していても、npm が最新のバージョン (現時点では 4.13.3) に更新します。3 つ目の方法として、yeoman という別のパッケージを使って Express アプリのスキャフォールディングを実行する方法もありますが、今回の目的の 1 つは MEAN における動的要素をすべて理解することなので、これは後ほど取り上げることにします。

"Hello Express"

Express をインストールしたら、恒例の "hello world" を Express で作成します。図 3 のコードは、app.js というファイルにあります。これは package.json が "main" のエントリとして所持しているファイルです。シンプルですが必要な項目はすべて含まれています。

図 3 Express で作成した Hello World コード

// Load modules
var express = require('express');
var debug = require('debug')('app');
// Create express instance
var app = express();
// Set up a simple route
app.get('/', function (req, res) {
  debug("/ requested");
  res.send('Hello World!');
});
// Start the server
var port = process.env.PORT || 3000;
debug("We picked up",port,"for the port");
var server = app.listen(port, function () {
  var host = server.address().address;
  var port = server.address().port;
  console.log('Example app listening at http://%s:%s', host, port);
});

最初の 2 行は、前回のコラムで取り上げた require を呼び出しています。現時点では、これで Node.js がモジュールを読み込みます。ECMAScript 6 ではこの部分が変わります。この 2 行によって、express パッケージと debug パッケージのそれぞれにアクセスできるようになります。require がフェッチする Express モジュールは、実際には、呼び出されたときに Express アプリケーション自体を呼び出す関数です。(慣例上) "app" にします。

次の行は、Express で "ルート" と呼ぶものをセットアップします。これは、多くの点で、最近の ASP.NET や ASP.NET MVC でよく使われるルーティング テーブルに似ていて、要求動詞 (get) を関数への相対 URL パス (この場合は "/") にマップします。この場合、これは "Hello World" に応答する匿名関数リテラルになります。この関数は、要求を受け取った後すぐに行を 1 つ出力するために、debug オブジェクトも使用します。

コードの最後の部分では、現在の環境をチェックして、(Azure にある) PORT 環境変数が指定されているかどうかを調べます。指定されていなければ、3000 をポートに割り当てます。その後、app オブジェクトにリッスンするよう指示します。これはブロッキング呼び出しで、着信すると、リッスンを開始するときに渡した匿名関数リテラルが実行されます。その後、プロセスは着信要求を待機し、要求が "/" に向けられていると想定して "Hello World" で応答します。

Express のデバッグ

前回説明したように、require の手順で使用した文字列を DEBUG 環境変数に設定しないと、debug 出力は表示されません。今回の例では、この文字列が "app" です。Express は、debug も使用します。DEBUG 変数に "*" を設定すると、Express の診断出力がすべて表示されます。定期的にデバッグを実行する場合に情報が少し多すぎますが、Express 初心者の方は、スクロールしながら確認すると便利です。これにより、さまざまな部分を理解し、いつ、何が呼び出されるかを把握できます。(要求が少しだけある) 出力例を図 4 に示します。

Express のデバッグ ログ
図 4 Express のデバッグ ログ

DEBUG に何も設定しなければ、デバッグがオフになります。すべてではなく 1 つ以上の debug ストリームを表示するには、次のように名前をコンマで区切ります。

DEBUG=app,express:router,express:router:layer

このコマンドは、これらの 3 つの debug ストリームの出力のみを表示します。

まとめ

多くの点で、Express は ASP.NET とよく似ています。これは、HTTP トラフィックの処理方法だけではありません。数十個の (または数百個の) 他のパッケージが依存して拡張する、"中央ハブ" のように機能するところまで似ています。たとえば serve-static パッケージは、画像やフォントなどの静的な (つまり、サーバー側で実行されていない) アセットのディレクトリを Express アプリに提供する、構築済みの方法として機能します。次回は、Express の要求オブジェクトと応答オブジェクトを使用する方法を取り上げる予定です (待ち切れない方は、expressjs.com (英語) で Express のドキュメントを参照してください)。それまでの間、コーディングを楽しんでください。


Ted Newardは、コンサルティング サービス会社の iTrellis で CTO を務めています。これまでに 100 本を超える記事を執筆している Ted は、さまざまな書籍を執筆および共同執筆していて、『Professional F# 2.0』(Wrox、2010 年、英語) もその 1 つです。F# MVP であり、世界中で講演を行っています。彼は定期的にコンサルティングを行い、開発者を指導しています。彼の連絡先は ted@tedneward.com (英語のみ) または ted@itrellis.com (英語のみ) です。

この記事のレビューに協力してくれた技術スタッフの Shawn Wildermuth に心より感謝いたします。
Shawn Wildermuth は、Microsoft MVP (ASP.NET/IIS) を 13 回受賞しています。ソフトウェア開発に関して 8 冊の書籍と数十本の記事を執筆しているほか、Pluralsight の執筆者を務めていて、15 を超えるコースに携わっています。また、彼は Wilder Minds (http://wilderminds.com、英語) のメンバーで、ブログは http://wildermuth.com (英語) です。