2

Javascript から Rails アプリのアセットを頻繁に参照する必要があります。assets.js.erb ファイルを作成し、そこにアセットへの参照を含める方法を見てきました。次の例と同様:すべての asset_path 値を構築して *.js.erb ファイルを回避します。

これはかなり厄介だと思います。マニフェスト生成にフックして同時に manifest.js を生成したいと思います。これを行うために次のことを思いつきましたhttps://gist.github.com/49d3f12bed298f0685a1

assets:precompile を実行すると問題なく動作しますが、開発のためには、この manifest.js を動的に生成する必要があります。ただし、これを行う適切な場所が見つかりません。/assets/* から /app/assets/ へのリクエストを開発モードでルーティングするミドルウェアはありますか? その段階でフックするのが適切でしょうか?

どんな提案でも大歓迎です。

4

1 に答える 1

2

スプロケットのソースといくつかのアクションパックのスプロケットのものも読んだ後、私はこのアプローチを思いつきました。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);

これにはまだいくつかの作業が必要ですが、私は正しい軌道に乗っていると思います。

于 2012-06-22T16:49:25.677 に答える