Technofara

Golangエンジニア!仕事で必要になって勉強した事とか、新しい事とか色々まとめたりを緩くやります。技術系と思考系だけにしておきます、

RequireJSを使ってモジュール管理

小言

Backboneを書いてると、依存がわかりにくくなってきたから、RequireJSを使って、モジュール単位で管理してみた内容をメモベースに書き起こしてみた。 そんな備忘録

BackboneJSを使って書いてると、、どんどん依存がわからなくなってくる。。

今回の投稿は、以前の http://shinofara.hateblo.jp/entry/2013/12/04/052121 の続き

準備

まずは、bowerでrequireJSを手に入れる。 以下の内容をbower.jsonに追加する。

"requirejs": "latest"

こんな感じかな

$ cat bower.json
{
    "name": "sample",
    "version": "0.0.0",
    "dependencies": {
        "jquery": "~2.0.0",
        "underscore": "latest",
        "backbone": "latest",
        "requirejs": "latest"
    }
}

インストール

./node_modules/.bin/bower install

確認

$ tree -L 1 src/javascripts/vender/
src/javascripts/vender/
├── backbone
├── jquery
├── requirejs
└── underscore

準備完了

サンプル作成

viewファイル

$ cat test.js
/**
 * 練習用のview
 */
define(
  ['jquery', 'backbone', 'templates/templates'], 
  function ($, Backbone, JST) {
    //jquery -> $
    //backbone -> Backbone
    //templates/templates.jsをJSTとして使いますって事
    //jqueryとbackboneについては次で説明
    
    return Backbone.View.extend({
      el: 'body',

      template: null,

      defaults: {
      },

      //イベント
      //シンプルにボタンクリックで2つの関数を実行しますよって事
      events: {
        'click #swithMainBtn': 'swithMainView',
        'click #swithDetailBtn': 'swithDetailView'
      },

      //初期化
      initialize: function() {
        this.reset();
      },

      //テンプレートを初期値に戻す
      reset: function() {
        this.template = JST['test'];
      },

      //JST template test
      render: function() {
        $('#content').html(this.template({name: 'shinofara'}));
      },

      swithMainView: function() {
        this.reset();
        this.render();
      },

      //JSTのtest2を使う
      swithDetailView: function() {
        this.template = JST['test2'];
        this.render();
      }
    });
  }
);

テンプレートファイルと呼ばれるものを準備

.htmlの前についてる文字列が JST['ほにゃらら']として定義されますよー。

なので、これはJST['test']

$ cat test.html
<h1><%- name %>さんのページ</h1>
<p class="big-desc">
トップページ
</p>
<a id='swithDetailBtn'>&gt;詳細を見る</a>

これはJST['test2']

$ cat test2.html
<h1><%- name %>さんのページ</h1>
<p class="big-desc">
詳細ページ
</p>
<a id='swithMainBtn'>&gt;トップに戻る</a>

htmlを書くだけでいいの? もちろん!そんなわけはなく、コンパイル処理を挟まないとダメ。

前回Gruntについて書いてるので導入等は省略

module.exports = function(grunt) {

  grunt.initConfig({

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

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

    watch: {
      scripts: {
        files: ['src/templates/**/*.html'],
        tasks: ['jst'],
        options: {
          spawn: false,
        },
      },
    }

  });

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

前回のままでも使えるけど、今回は

amd: true

を追加しました。簡単に動作説明をしておくと グローバル定義でJSTとするのではなく、JSTの中身をreturnするから あとは受け取る側で好きな変数に定義してねって事。(個人的解釈!)

grunt jst

Backboneとかその他もろもろの定義

$ cat base.js

requirejs.config({
  baseUrl: 'src/javascripts',
    //To get timely, correct error triggers in IE, force a define/shim exports check.
    enforceDefine: true,
    shim: {
      'jquery': { exports: '$' },
      'underscore': { exports: '_' },
      'backbone': {
        deps: ['jquery', 'underscore'],
        exports: 'Backbone'
      }
    },
    paths: {
        //jqueryって名前で/src/javascripts/vender/jquery/jquery.min.jsを定義
      jquery: [
        '/src/javascripts/vender/jquery/jquery.min'
      ],
      underscore: [
        "/src/javascripts/vender/underscore/underscore-min"
      ],
      backbone: [
        "/src/javascripts/vender/backbone/backbone-min"
      ]
    }
});

アプリケーション単位で作る、ファイル(web MVCで言うCにあたるかどうかなかんじ)

$ cat app.js
require(['test'], function(helloView) {
    //backbone viewを使う
    var hellow = new helloView();
    hellow.render();
});

最後は読み込み処理を追加

今回はindex.htmlで作成

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html lang="ja">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<link rel="stylesheet" href="css/bass.css" />
</head>
<body>
  <div class="top-left" id="content">
    <h1>ロード中....</h1>
  </div> <!-- End of Top-Left -->
  <script src='/src/javascripts/vender/requirejs/require.js'></script>
  <script src='/src/javascripts/base.js'></script>
  <script src='/src/javascripts/app.js'></script>
</body>
</html>

はい、完了

あとはindex.htmlをブラウザで確認したらOK http://localhostとかなんでも!