Backboneのテンプレート開発は、Grunt使ってJSTに変換すると捗る

Backbone使うときにちょっと考えないといけないのが、テンプレートをどこに書くかという問題です。

「ToDoアプリを作ってみよう!」的なチュートリアルは、大抵、Underscore.jsのテンプ レートをindex.htmlのなかに書いていくパターンが多いかと思います。

こんな感じに。

<!DOCTYPE HTML>
<html>
<head>
  <meta charset="utf-8">
  <title>Backbone Tutorial</title>
</head>
<body>
  ...

  <script type="text/template" id="item-template">
      ...
  </script>

  ...
</body>
</html>  


Backboneからは以下のように、jQueryを使ってテンプレート化します。

var itemView = Backbone.View.extend({
  ...

  template: _.template($('#item-template').html()),

  ...
});

これ、テンプレートが少ないうちはいいのですが、多くなってくると管理が大変です。

テンプレートはテンプレートとして別のファイルに分けて開発したくなりますね。
かと言ってファイルが多くなると、それはそれでhtmlから読み込むのが面倒だったり。。

Railsとか使っていると、Backboneのgemを入れればそのへんの環境もまとめて整えてくれるのですが、クライアントサイドだけだと自分で環境を整えないといけません。

という状況で、Gruntが活躍してくれました。

プラグインのインストール

今回はcontrib-jstというプラグインを使いました。(次はcontrib-handlebarsを使ってみようと思います)
まずはそいつをインストールします。

$ npm install grunt-contrib-jst --save-dev

Gruntの環境がない方はこちらを参照

テンプレート用ディレクトリの準備

今回は以下のようなディレクトリ構成にしました。

|-- build
|   |-- images
|   |-- javascripts # ここにJSTファイルが置かれる
|   |-- stylesheets
|   `-- index.html
|-- src
|   |-- images
|   |-- javascripts
|   |-- stylesheets
|   |-- templates # ここにテンプレートファイルを置いておく
|   `-- index.html
|-- Gruntfile.js


Gruntfile.jsの編集

Gruntfile.jsというファイルをルートディレクトリに作成し、以下のように編集します。

module.exports = function(grunt) {

  grunt.initConfig({

    pkg: grunt.file.readJSON('package.json'),

    jst: {
      compile: {
        options: {
          templateSettings: {
            interpolate : /\{\{(.+?)\}\}/g
          },
          processName: function(filename) {
            return filename.replace(/(src\/templates\/|.html)/g, '');
          }
        },
        files: {
          'src/javascripts/templates/templates.js': [
            'src/templates/**/*.html'
          ]
        }
      }
    }

  });

  grunt.loadNpmTasks('grunt-contrib-jst');
}

これで環境は整いました。

src/templates 以下に .htmlという拡張子をつけてUnderscore.jsのテンプレート入れておけば、まとめてJSTファイルにしてくれます。
(今回は.htmlという拡張子をつけるようにしましたが、.tpmlでも何でもいいと思います)

ワークフロー

たとえば、hello.htmlを置いてコマンドを実行すると、build/javascripts以下にtemplates.jsというファイルが作成されます。

$ grunt jst


htmlでtemplates.jsを読み込んでおけば、Backboneからは以下のようにしてテンプレート使うことができます。

var helloView = Backbone.View.extend({

  template: JST['hello'],

  render: function() {
    this.setElement(this.template());
    return this;
  }

});


これですっきり!