tech memorandom

Webに関して調査したことや、メディアアート系(Max,Processing)で調査したことなどを書いていきます。

Ruby On Rails AssetPipelineで読み込まれるJSの順番指定について

サーバへの負荷を経験するたに1アクセスあたりのコネクション数をできるだけ減らすためにcssやjsを1回で取得できるようにする、というのが最近の当たり前だと思うけど、この作業がけっこう手間だったりする。Ruby On Railsの3.1あたりから実装されたAssetPipelineを使うとasset下にあるJSをまとめて1ファイルにして圧縮をかけてくれる、というかなり便利な機能がある。

ファイルを増やすたびに定義ファイルを更新しなくてもいい、というのは全く幸せなのだが、JSは読み込む順番によっては参照しようとしているオブジェクトがまだよみこまれていないのに参照してしまう、といった現象が発生してしまう。

このあたりの回避策について調べたのでメモ
デフォルトの設定は以下の通り。requireのあとにライブラリ名を記述する、require_tree . がディレクトリ内のJSを圧縮対象になる。
この書き方の場合、最初にJQueryが読み込まれて、そのあとに他のJSが順不同で呼ばれる。

For example, a new Rails application includes a default app/assets/javascripts/application.js file which contains the following lines:

// ...
//= require jquery
//= require jquery_ujs
//= require_tree .

自前でつくったライブラリはどうするのか。力技でいくなら追加するたびにここに記述してもいいけど、ファイル数が増えるとうんざりしそう。
そのファイルをcatしてもいいと思うけどそれだと本末転倒な気もする。

個人的にはファイル追加だけで済ませたい。

公式マニュアルをみるとrequire_directoryを使えばいいよと書いてあったので早速ためしてみた。(といってもかなり前にやったことを書いているわけですが・・・)

この記述の定義の目的はライブラリをよんで、パッケージ化されたライブラリの読みこみ、自分で定義したクラス群、それらを制御するアプリケーションクラス、最終的アプリケーションをブートするmain関数がはいったプログラム、といった順番で読んでほしい、という意図で分けました。

//= require jquery
//= require jquery_ujs
//= require jquery.transit.min
//= require underscore
//= require backbone-min
//= require underscore
//= require_directory ./package
//= require_directory ./classes
//= require_directory ./Apps
//= require_directory ./main

階層はこんな感じです。

├── Apps
│   └── AppView.coffee
├── application.js
├── classes
│   ├── CycleModel.coffee
│   └── CycleView.coffee
├── main
│   └── main.coffee
└── package
    └── package.coffee

これベストかというとちょっとわからりませんが現状はこんなところで。
Classの中でも依存関係があったりするのでもうちょっと細かい階層分けが必要になるかもしれません。

他にも色々設定があるのでRailsGuideをチェックしてみださい。

spinejsは自動的に依存関係を解消する仕組みが実装されていました。
簡単に試してみてなるほどと思ったのですが、長くなるのでこのへんで。