2015年5月22日金曜日

Express4で最速テンプレートエンジンECTを使う簡単なサンプル

Express4プロジェクトの雛形を生成すると、デフォルトのテンプレートエンジンとして Jade が自動的に導入されるのですが、 こちらは速度的な部分で少し不満が残ります。
そこで Jade の代替として登場するのが、ECT です。ECT は自サイトでテンプレートエンジン最速を謳っています。ECT本家サイトのベンチマークを見ると、その処理スピードはなんとJadeの8倍の速さとなっています。
今現在どのテンプレートエンジンを導入しようかとお悩み中の方は、迷わず ECT の導入を検討すべきではないでしょうか。

というわけで今回は ECT をサクッと試したい人向けに超簡単なサンプルを用意してみました。


プロジェクト雛形を生成


まずは Express4プロジェクトを生成しておきましょう。
今回はプロジェクト名を ect-example としておきます。
※Expressがインストール済みであることが前提です。

$ express ect-example

ここで生成された雛形は、まだテンプレートエンジンにデフォルトの Jade が使われていますが、慌てないで下さい。これから ECT を使うように作り変えていきます。

まずは余計なファイルを全て削除します。
削除対象は下記のとおり。

・views 配下の全ての jade ファイル
・routes 配下の users.js

次に views 配下に以下の ect ファイルを新規作成しておきます。

・layout.ect
・index.ect
・list.ect
・footer.ect
・error.ect

ここまででプロジェクト構成はこのようになります。



ECTをインストール


$ sudo npm install --save ect

ectをインストールすると、package.json はこのようになります。
{
  "name": "ect-example",
  "version": "0.0.0",
  "private": true,
  "scripts": {
    "start": "node ./bin/www"
  },
  "dependencies": {
    "body-parser": "~1.12.0",
    "cookie-parser": "~1.3.4",
    "debug": "~2.1.1",
    "ect": "^0.5.9",
    "express": "~4.12.2",
    "morgan": "~1.5.1",
    "serve-favicon": "~2.2.0"
  }
}

app.jsを編集


app.jsを編集します。
重要な部分は太字にしておきました。

app.js
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');

var app = express();

// ECT view engine setup
var ECT = require('ect');
var ectRenderer = ECT({ watch: true, root: __dirname + '/views', ext : '.ect' });
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ect');
app.engine('ect', ectRenderer.render);

// routes setup
var routes = require('./routes/index');
app.use('/', routes);

// uncomment after placing your favicon in /public
//app.use(favicon(__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')));

// catch 404 and forward to error handler
app.use(function(req, res, next) {
  var err = new Error('Not Found');
  err.status = 404;
  next(err);
});

// error handlers

// development error handler
// will print stacktrace
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: {}
  });
});


module.exports = app;

routesの編集


routes/index.js
var express = require('express');
var router = express.Router();

/* GET home page. */
router.get('/', function(req, res, next) {
  var data = {
    title: 'Hello, world!',
    id: 'abc123',
    links: [{
      name: 'Google',
      url: 'http://google.com/'
    }, {
      name: 'Facebook',
      url: 'http://facebook.com/'
    }, {
      name: 'Twitter',
      url: 'http://twitter.com/'
    }],
    upperHelper: function(string) {
      return string.toUpperCase();
    }
  };
  res.render('index', data);
});

module.exports = router;

GET / されると次の画面 (index.ect) にjsonが渡されます。
upperHelperのような関数も渡すことができます。

ectファイルの編集


最後に views/*.ect (画面定義ファイル) を編集します。

layout.ect (全画面共通のレイアウト)
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title><%- @title %></title>
  </head>
  <body>
    <% content %>
    <% include 'footer' %>
  </body>
</html>

index.ect (GET / された時に呼ばれる画面)
<% extend 'layout' %>

<div id="<%- @id %>">
  <h1><%- @upperHelper @title %></h1>
  <% include 'list' %>
</div>

<div>
  Escaped with <i><%= %></i>: <%= "<b>This is bold</b>"  %><br>
  Unescaped with <i><%- %></i>: <%- "<b>This is bold</b>"  %><br>
</div>

<% block 'footer-info' : %>
  <div class="right">page: main</div>
<% end %>

注目:
上記の @upperHelper @title でタイトルを大文字化しています。
upperHelperは routes/index.js から渡されてきた関数です。

list.ect (index.ect 内でincludeされる部品)
<% linkHelper = (link) -> %>
  <li><a href="<%- link.url %>"><%- link.name %></a></li>
<% end %>

<% if @links?.length : %>
  <ul>
    <% for link in @links : %>
      <%- linkHelper link %>
    <% end %>
  </ul>
<% else : %>
  <p>List is empty</p>
<% end %>

footer.ect (layout.ectでincludeされる部品)
<div id="footer">
  <div class="left">Generated by ECT</div>
  <% content 'footer-info' %>
</div>

error.ect (error時に呼ばれる画面)
<html>
<head>
  <meta charset="utf-8">
  <title>Error <%= @error.status %></title>
</head>
<body>
  <span>
  Error Status: <%= @error.status %>
  <hr>
  <pre><%= @error.stack %></pre>
  </span>
</body>
</html>

実行


$ npm start

アプリを起動後、http://localhost:3000 にアクセスすると以下のような画面が表示されます。



以上となります。

0 件のコメント:

コメントを投稿