問題の良い解決策を実際に考え出すには、おそらくSprocketsとSprocketsとRailsの統合のソースを掘り下げる必要がありますが、これらのポインターのいくつかが役立つことを願っています。
まず、チェックアウトSprockets::Helpers::RailsHelper#javascript_include_tag
:
1 def javascript_include_tag(*sources)
2 options = sources.extract_options!
3 debug = options.key?(:debug) ? options.delete(:debug) : debug_assets?
4 body = options.key?(:body) ? options.delete(:body) : false
5 digest = options.key?(:digest) ? options.delete(:digest) : digest_assets?
6
7 sources.collect do |source|
8 if debug && asset = asset_paths.asset_for(source, 'js')
9 asset.to_a.map { |dep|
10 super(dep.pathname.to_s, { :src => path_to_asset(dep, :ext => 'js', :body => true, :digest => digest) }.merge!(options))
11 }
12 else
13 super(source.to_s, { :src => path_to_asset(source, :ext => 'js', :body => body, :digest => digest) }.merge!(options))
14 end
15 end.join("\n").html_safe
16 end
大まかに言えば、このメソッドは次のことを行います。
- すべてを1つのファイルに連結するか、すべてのアセットを個別に含めるかを決定します(3行目)。
- アセットファイル名にダイジェスト文字列を含める必要があるかどうかを判断します(5行目)。
- 指定されたソースファイルごと
Sprockets::Asset
に、そのソースファイルに対応するオブジェクトを取得します(8行目)。
Asset
デバッグしている場合は、このメソッドに必要なそれぞれを使用してスーパークラスメソッドを呼び出します。Sprockets::Asset#to_a
そのような配列を返します(9〜10行目)。
Asset
デバッグしていない場合(または何らかの理由でオブジェクトの取得に失敗した場合)、トップレベルAsset
(または文字列としてのソースファイル名)を使用してスーパークラスメソッドを呼び出します(13行目)。
これらの方法の多くは非常に単純で、設定した環境にのみ依存します。例digest_assets?
:
def digest_assets?
Rails.application.config.assets.digest
end
Rails.application.assets
この構成の一部は、それ自体がSprockets::Environment
オブジェクトであるに保存されます。Railsコンソールで実際にこれを試して、慣れることができます(まだ慣れていない場合は、awesome_print gemを強くお勧めします):
1.9.3p194 :001 > Rails.application.assets.class
Sprockets::Environment < Sprockets::Base
1.9.3p194 :002 > Rails.application.assets['application.js'].class
Sprockets::BundledAsset < Sprockets::Asset
1.9.3p194 :003 > Rails.application.assets['application.js'].to_a.map(&:digest)
[
[ 0] "6bb424b2409c6a5fb28acd15cc184b16",
[ 1] "0ff3e5680ead3dadeee021c144835311",
[ 2] "4c908739f93e83bda6b5e84f7ab10a29",
[ 3] "319003f54b9408b4e41b0199e1848423",
[ 4] "3f52cd966b6bb99a8f7994f5dcd7767f",
[ 5] "c50a6aac16f6a69deeb722fe51e36c54",
# ...
]
つまり、基本的に、Sprocketsはアセットの依存関係、連結、およびダイジェストを決定する責任があり、Railsはそれをヘルパーと結び付けるだけです。フレームワークでこの動作をかなり簡単な方法で複製できるはずです。