スプロケットのソースといくつかのアクションパックのスプロケットのものも読んだ後、私はこのアプローチを思いつきました。app/assets/javascripts/assets.js.erb などに入れるだけです。Sprockets::Environment の each_logical_path メソッドを使用してすべてのアセット ファイルを反復し、そのパスで Asset オブジェクトをインスタンス化します。rails 環境でアセット ダイジェストが有効になっているかどうかに応じて、正しいアセット パスが返されます。
<%
manifest = {}
app = Rails.application
env = app.assets
env.each_logical_path do |logical_path|
if File.basename(logical_path)[/[^\.]+/, 0] == 'index'
logical_path.sub!(/\/index\./, '.')
end
# grabbed from Sprockets::Environment#find_asset
pathname = Pathname.new(logical_path)
if pathname.absolute?
return unless stat(pathname)
logical_path = attributes_for(pathname).logical_path
else
begin
pathname = resolve(logical_path)
rescue Sprockets::FileNotFound
return nil
end
end
asset = Sprockets::Asset.new(env, logical_path, pathname)
manifest[logical_path] = app.config.assets.digest ? asset.digest_path : asset.logical_path
end
%>
!function(window, document, undefined){
var assets = <%= ActiveSupport::JSON.encode(manifest) %>;
var asset_path = function(path){
if(assets.hasOwnProperty(path)){
return '/assets/' + assets[path];
}
else{
throw Error('missing asset: ' + path);
}
};
window.asset_path = asset_path;
window.asset_url = function(path){ return window.location.protocol + '//' + window.location.host + asset_path(path); };
}(window, document);
これにはまだいくつかの作業が必要ですが、私は正しい軌道に乗っていると思います。