使用 Sprockets 生成 JavaScript 清单



我们经常需要从Javascript中引用rails应用程序资产。我见过创建 assets.js.erb 文件并在其中包含对资产的引用的方法。类似于此处的示例:通过构建所有asset_path值来避免 *.js.erb 文件

我认为这很混乱,我想同时挂接到清单生成并生成清单.js。我想出了以下方法来做这个 https://gist.github.com/49d3f12bed298f0685a1

当您运行 assets:precompile 时,这工作正常,但是,对于开发,我需要动态生成此清单.js。不过,我找不到合适的地方来做这件事。在开发模式下,是否有一些中间件将/assets/* 的请求路由到/app/assets//,在那个阶段挂钩是否合适?

欢迎任何建议。

在阅读了链轮源代码和一些动作包链轮的东西后,我一直在研究这个问题,我想出了这种方法。只需将其放在app/assets/javascripts/assets.js.erb或类似的东西中即可。它使用 Sprockets::Environment 中的 each_logical_path 方法遍历所有资产文件,然后使用该路径实例化资产对象。返回正确的资产路径取决于是否为您的 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);

这仍然需要一些工作,但我认为我走在正确的轨道上。

相关内容

  • 没有找到相关文章

最新更新