在阅读了 sprockets 源代码和一些 actionpack sprockets 的东西之后,我一直在努力解决这个问题,我想出了这种方法。只需将它放在 app/assets/javascripts/assets.js.erb 或类似的地方。它使用 Sprockets::Environment 中的 each_logical_path 方法迭代所有资产文件,然后使用该路径实例化一个资产对象。根据是否为您的 rails env 启用资产摘要,返回正确的资产路径。
<%
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);
这仍然需要一些工作,但我认为我在正确的轨道上。