Edited at

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でもバンドルしたのですが、出力された内容が微妙に違うので自信ないです。