今回のエントリ内容は、このエントリの続編的な内容です。実際に作業する準備の手順も含まれているので、実際に試す前に一度内容をご確認ください:
Bluemix 上の Node.js を使う


Express は Node.js 上で使う MVC フレームワークです。いわゆる "MEAN"(mongoDB + Express + AngularJS + Node.js) スタックを構成する要素の1つです。

また EJS は Node.js 上で利用可能なテンプレートエンジンです。HTML ベースのテンプレートにルック&フィールの UI をデザインし、その中身を変数化して動的に埋めていくことで Web アプリケーションの見栄えを作っていくことができます。

設計とデザイン(見た目)とを別チームに分けて開発するようなスタイルでは、こういったテンプレートエンジンと MVC フレームワークを活用して、デザインチームにテンプレートを、設計チームに MVC を含むプログラミング部分を担当してもらう、といった体制で開発することは一般的です。


Express も EJS も、Node.js ではそれなりにメジャーなコンポーネントで、通常はパッケージマネージャーである npm を使ってインストールして利用するものです。では npm 環境が使えない Bluemix では、これらをどのようにして導入して使えばいいのか? という疑問が出てきます。

その答は、上記の前エントリ内でも述べていますが、package.json ファイルを使って必要なモジュールを動的に指定して用意する、ということになります。Express も EJS もこの方法で Bluemix 内の Node.js ランタイム内に導入可能です。以下にその具体的な手順を紹介します。


今回作成するファイルはこの3つです:
|- public/
|    |- hello.ejs
|- app.js
|- package.json

まずはテンプレートを用意します。 public というフォルダを作り、その下に hello.ejs というテキストファイルを以下の内容で(UTF-8 で)作ります。これが見栄えの部分です:
<html>
<h1><%= title %></h1>
<div><%- content %></div>
<div><%= n %> views</div>
</html>

title, content, n という3つの変数が定義されていて、それらの値を使った HTML が記述されています。EJS ではテンプレート内での変数の書き方は2種類あって、<%= ~ %> で括られた部分はエスケープされて出力され、<%- ~ %> で括られた箇所はエスケープされません(HTML タグが HTML タグとして有効になります)。今回の例では content 変数に HTML タグが含まれている場合は HTML タグが有効になります。


次はシステム設計です。 前回の server.js を元に、app.js を以下の内容で作成します:
var express = require( 'express' );
var app = express();

var fs = require( 'fs' );
var ejs = require( 'ejs' );
var template = fs.readFileSync( __dirname + '/public/hello.ejs', 'utf-8' );

var cfenv = require( 'cfenv' );
var appEnv = cfenv.getAppEnv();

var n = 0;

app.get( '/', function( req, res ){
  n ++;
  var data = ejs.render( template, {
    title: "ハローワールド!",
    content: "ようこそ <strong>Express</strong> + <i>EJS</i> の世界へ",
    n: n
  });
  
  res.writeHead( 200, { 'Content-Type': 'text/html' } );
  res.write( data );
  res.end();
});

app.listen( appEnv.port );



Express を使って http アプリケーションが作られ、ドキュメントルート('/')へのリクエスト時に表示する内容は EJS のテンプレートをベースに、その変数部分だけが動的に指定されて表示されるようになっています(EJS のテンプレートパスを指定する際に fs モジュールも使っています)。変数 title, content, n は変数 data 内にまとめて指定しています。なお変数 content の内容は HTML タグを含むテキストです。また変数 n はイクンリメント変数なので、リロードする度に1つずつ値が増えるようにしています。 cfenv モジュールに関しては上述の前回の内容を参照してください。

最後に package.json を以下の内容で用意します:
{
  "scripts": {
    "start": "node app.js"
  },
  "dependencies": {
    "cfenv": "1.0.x",
    "express": "4.12.x",
    "ejs": "2.3.x",
    "fs": "0.0.x"
  }
}

"scripts" の中で app.js を起動するよう指定している箇所は前回と同様です。加えて、今回は Express, EJS(とファイルシステム利用のための FS )のモジュールを利用したいので、"dependencies" の中でこれらのモジュールを動的にロードするよう指定しています。


これら3つのファイルが用意できたら、cf ツールで Bluemix 上の Node.js ランタイムにプッシュして、ブラウザでドキュメントルートにアクセスしてみます:
2015100705


hello.ejs テンプレートをベースとしたページが表示されており、また変数 content に含まれている HTML タグが有効になっていることがわかると思います。また同じページをリロードすると変数 n の値がインクリメントされて、1つずつ増えていくのがわかります:
2015100706


npm でインストールしていたモジュールを package.json で指定して動的にインストールする、という違いが分かってしまえば、Bluemix 上でもそんなに違和感なく Node.js 環境が使えるようになります。