Создание манифеста JavaScript с помощью звездочек

Нам часто нужно ссылаться на ресурсы приложения rails из нашего Javascript. Я видел методы, где вы создаете файл assets.js.erb и включаете туда свои ссылки на ресурсы. Аналогично приведенному ниже примеру: избегайте файлов *.js.erb, создавая все значения asset_path

Я думаю, что это довольно грязно, и я хотел бы подключиться к генерации манифеста и создать файл manifest.js одновременно. Я придумал следующее, чтобы сделать это https://gist.github.com/49d3f12bed298f0685a1

Это прекрасно работает, когда вы запускаете assets: precompile, однако для разработки мне нужно, чтобы этот manifest.js генерировался динамически. Я не могу найти подходящее место для этого, хотя. Есть ли какое-то промежуточное программное обеспечение, которое направляет запросы в / assets / * в / app / assets // в режиме разработки, было бы целесообразно подключить на этом этапе?

Любые предложения будут приветствоваться.

1 ответ

Я работал над этим после прочтения источника звездочек и некоторых вещей из пакета actionpack, и я придумал этот подход. Просто поместите его в app/assets/javascripts/assets.js.erb или что-то в этом роде. Он использует метод each_logical_path из Sprockets::Environment для итерации по всем файлам активов, а затем создает экземпляр объекта 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);

Это все еще требует некоторой работы, но я думаю, что я на правильном пути.

Другие вопросы по тегам