grunt
marionette
browserify
backbone

Backbone.MarionetteアプリをBrowserifyでバンドルする(Grunt編)

More than 3 years have passed since last update.

Backbone.MarionetteとHandlebarsを使ったアプリをBrowserifyでバンドルするメモです。

フレームワークやライブラリとアプリを分離してバンドルします。

GruntfileはCoffeeScriptで記述しています。

package.json

フレームワーク

"jquery": "~2.1.1",
"underscore": "~1.7.0",
"backbone": "~1.1.2",
"backbone.marionette": "~2.3.0",
"handlebars": "^2.0.0"

Grunt

"grunt": "~0.4.5",
"browserify": "^8.0.2",
"grunt-browserify": "~3.2.1",
"remapify": "^1.3.0",
"hbsfy": "^2.2.1",

Gruntfile.coffee

vendor.jsには、jquery,underscore,backbone,backbone.marionette,handlebarsをバンドルします。
app.jsにはアプリケーションとhandlebarsのテンプレートをバンドルします。

browserifyタスク
browserify:
options:
  preBundleCB: (b) ->
    b.plugin remapify, [
      {
        cwd: "./assets/js"
        src: "*.js"
        expose: "app"
      }
    ]

app:
  files:
    "<%= dir.dst %>/js/app.js": [
    "<%= dir.src %>/js/*.js"
  ]

  options:
    transform: ["hbsfy"]
    ignore: ["<%= dir.src %>/js/vendor.js"]
    external: [
      "jquery"
      "underscore"
      "backbone"
      "backbone.marionette"
      "handlebars"
    ]
    alias: [
      "<%= dir.hbs %>/template1.hbs:app/template/template1"
      "<%= dir.hbs %>/template2.hbs:app/template/template2"
    ]

vendor:
  files:
    "<%= dir.dst %>/js/vendor.js": ["<%= dir.src %>/js/vendor.js"]

  options:
    alias: [
      "jquery"
      "underscore"
      "backbone"
      "backbone.marionette"
      "handlebars"
    ]

vendor.js

vendor.jsは以下のとおりです。

var Backbone = require('backbone');
Backbone.$ = require('jquery');
require('backbone.marionette');

マッピングとエイリアス

相対パスでrequireのパスを記述するのが面倒なので、マッピングとエイリアスを利用します。

grunt-browserifyの2.x以前ではaliasMappingが使えたのですが、今では(3.2.1)使えなくなってしまいました。2.x以降で同様なことを行うには、remapifyを利用すればできるようですが、思ったように動作しませんでした。

https://github.com/jmreidy/grunt-browserify

A note on alias mappings, which was a functionality pre 2.0
that was removed: its behavior can be reproduced with @joeybaker's remapify plugin,
as demonstrated in the code below:

具体的には、以下のようにbrowserifyタスクの共通optionsでremapifyにマッピング情報(.jsと.hbs)を設定したいのですが、引数のマッピング情報を二つ以上渡すと、"Fatal error: Cannot read property '1' of null"となります。
これも微妙でcwdで指定したパスにファイルが存在しなければ、とりあえずエラーは回避できるという状況です。

remapify = require 'remapify'

browserify:
  options:
    preBundleCB: (b) ->
      b.plugin remapify, [
        {
          cwd: "./assets/js"
          src: "*.js"
          expose: "app"
        }
        {
          cwd: "./template"
          src: "*.hbs"
          expose: "app/template"
        }
      ]

仕方なく、hbsファイルに関してはaliasを併用して、動作するようにしましたが、ここは改善したいところです。

これで動作していますが、ただしくバンドルを分離しているのか、ちょっと不安です。Gulpでもバンドルしたのですが、出力された内容が微妙に違うので自信ないです。