« Node.js + WebSocket + Backbone.jsのすすめ | トップページ | Backbone.js入門 »

2012年12月20日 (木)

Asset Pipelineのすすめ

Backbone.js Advent Calendarの20日目です。

Railsを使っている人なら知っているけど、他の言語の
フレームワークを使っている人は知らないかもしれない
Asset Pipelineについて書きます。

Railsは3.1からSprocketsと呼ばれるライブラリを使って、
Asset Pipelineという仕組みを導入しました。
初めは仕組みがややこしく、デフォルトで導入しなくても
よかったんじゃ?と思っていましたが、Backbone.jsを使う
ようになって、Backbone.jsユーザにとっては、神機能だと
いうことがわかるようになりました。
Node.jsにもmincerというSprocketsのクローンがあります。
(説明はまた後で)

それではここからAsset Pipelineって何、Backbone.jsに
とって何がうれしいの?を述べます。
Asset PipelineはManifestに従ってJavaScriptもしくはCSS
を生成するためのツールです。
Manifestとは下記のようにファイルの先頭にどの順番でどの
ファイルを展開するかを指定することです。
blog.js.coffee
#= require_self             <-自分自身を展開
#= require backbone  <- パス直下のbackbone.jsを展開
#= require_tree ./templates <- templates,blogsディレクトリ配下を
#= require_tree ./blogs   <- サブディレクトリも含めて再帰的に展開
window.Blog =
  Models: {}
  Collections: {}
  Routers: {}
  Views: {}

Manifestで指定されたファイル or ディレクトリ配下の
ファイルを展開し、ひとつのファイルにまとめます。
ひとつのファイルにまとめることで、Webブラウザから
アクセスするパスはひとつだけですむようになり、描画まで
の時間が大幅に短縮されます。
さらにSprocketsの場合は、minifyといって変数名を短縮
したり、余計な空白を削除することでファイルを小さくし、
さらに圧縮可能なブラウザ用に圧縮済みのファイルも用意
します。
Backbone.jsでSingle Page Applicationを作成した場合は、
開始時に大量のJavaScriptを読み込むため時間がかかりやすい
ですが、それを大幅に軽減してくれます。

まとめたファイル名にはフィンガープリントが末尾に付加
されており、内容が変わった場合は、ファイル名が変わる
ことでキャッシュがクリアされる仕組みになっています。

また開発時は、MiddleWare(RailsであればRack,Node.js
ではconnect)にマウントすれば、Webサーバを再起動せずに
ファイルの更新がクライアントへの応答に反映されます。
これは動的にコンパイルを行っているため負荷がかかりますが、
本番時にはその機能を無効にし、予めコンパイルした静的
ファイルを用意することでレスポンスの高速化を行うことが
できます。

JavaScriptのファイルを生成する場合は、元のファイルは
JavaScriptだけでなく、CoffeeScriptがあればそれを
コンパイルしてJavaScriptに変換したものを展開して
くれます。
CSSのファイルを生成する場合は、元のファイルがLESS、
SASS、Stylusだった場合はそれをコンパイルしてCSSを
生成してくれます。
ejsの拡張子があるものに関してはejsの評価結果をJavaScript
やCSSに反映してくれます。
これは環境変数によって設定を変えたJavaScriptやCSSを
用意したい場合に便利です。

さらにBackbone.jsユーザにとって嬉しいことは、JST
(JavaScriptテンプレート)に対応していることです。
これによりTemplateのHTMLを別ファイルに切り出す
ことができます。
11日目のAdvent CalendarでAjaxによって別ファイル
のTemplateを呼び出す方法が記載されていましたが、
Asset Piplelineを使えばコンパイルにより静的に
Viewファイルのtemplateが作成されます。
post_view.js
 Blog.Views.Posts ||= {}
class Blog.Views.Posts.PostView extends Backbone.View
  template: JST["templates/posts/post"]
  events:
    "click .destroy" : "destroy"
 
tagName: "tr"
 
destroy: () ->
   
@model.destroy()
   
return false
 
render: ->
    $
(@el).html(@template(@model.toJSON()))
   
return this
templates/post/post.jst.hamlc
%td= @title
%td= @content
%td
  %a{href: "#/#{@id}" ;} Show
%td
  %a{href: "#/#{@id}/edit"} Edit
%td
  %a{href: "#/#{ @id}/destroy< /b>",class: "destroy"} Destroy
JSTのTemplate元のフォーマットがSprocketsの場合
はEJSもしくはEcoですが、mincerの場合は Haml Coffee
もしくはJadeになります。
mincerのほうは癖があり、プログラではないデザイナさん
には大変ということと、Railsからの移行を考えるとEJSを
使いたいということもあり、拡張子がjst.ejsの場合はJST
展開する修正を行ったmincerを作りました。

SprocketsはRails標準ということもあり、ドキュメントが
たくさんあるのでここでは説明せず、あまり知られていない
mincerについて述べます。
以前紹介したサンプルアプリにもmincerが使われています。

本番環境(静的にコンパイルする)の場合

node_modules/mincer/bin/mincer.js -I app/assets/javascript -o public/assets   /絶対パス/app/assets/javascript/blogs.js.coffee

npm install mincerでnode_modules配下にmincerが
インストールされるのでそれを実行
-I で読み込む元のJavaScriptファイルがある場所
-o でできあがったファイルを置くディレクトリ
最後にコンパイルしたいManifestつきのファイル名を
絶対パスで指定します。
(私の環境では絶対パス以外なぜかうまくいかなかった。)

開発環境の場合
app.configure('development', function(){
  var Mincer  = require('mincer');
  var environment = new Mincer.Environment();
  environment.appendPath(__dirname + '/app/assets/javascript');
  app.use('/assets', Mincer.createServer(environment));
  app.use(express.errorHandler());
});
上記をメインのjs(app.js? or server.js)に記述すると、
/assets/ファイル(拡張子なし)で/app/assets/javascript配下の
ManifestつきのCoffeeScriptなりJavaScriptファイルを参照できる
ようになります。
Node.jsを再起動することなく、JavaScriptのファイルの変更が
反映されます。

Happy Backbone!!

|

« Node.js + WebSocket + Backbone.jsのすすめ | トップページ | Backbone.js入門 »

backbone.js」カテゴリの記事

コメント

コメントを書く



(ウェブ上には掲載しません)




トラックバック

この記事のトラックバックURL:
http://app.cocolog-nifty.com/t/trackback/68673/56354497

この記事へのトラックバック一覧です: Asset Pipelineのすすめ:

« Node.js + WebSocket + Backbone.jsのすすめ | トップページ | Backbone.js入門 »