在开发中禁用Sprockets资产缓存

时间:2013-06-06 19:06:08

标签: ruby-on-rails ruby asset-pipeline rack sprockets

我正在使用Rails 3.2.13和Rails Asset Pipeline。我想使用资产管道,所以我可以使用SASS和CoffeeScript和ERB作为我的资产,并让Pipeline自动编译它们,所以我不能在开发中关闭管道。我不是在开发中预编译资产,甚至没有public/assets/目录。

但是,当我对包含文件进行更改时,例如对_partial.html.erb文件中包含(呈现)的layout.html.erb文件进行更改,而不更改包含本身的文件(在此示例layout.html.erb),Sprockets没有检测到更改并使缓存无效,因此我不断获得相同的陈旧文件。当我在积极开发中执行此操作时,我想禁用任何资产缓存,以便我可以对每个请求进行更改,但我无法弄清楚如何执行此操作。我在development.rb

中设置了以下所有内容
config.action_controller.perform_caching = false
config.action_dispatch.rack_cache =  nil
config.middleware.delete Rack::Cache
config.assets.debug = true
config.assets.compress = false
config.cache_classes = false

尽管如此,即使这样,文件也会显示在tmp/cache/assets/tmp/cache/sass/下,并且未来的请求也无法进行更改。现在,每次我想看到更改时,我都必须手动删除这些目录。

不幸的是,资产管道RoR指南的How Caching Works部分的全部内容是:

  

Sprockets使用默认的Rails缓存存储来缓存资产   开发和生产。

     

TODO:添加有关更改默认商店的详细信息。

那么,我如何让Sprockets按需编译资产但不缓存结果呢?

3 个答案:

答案 0 :(得分:29)

这是神奇的咒语:

config.assets.cache_store = :null_store  # Disables the Asset cache
config.sass.cache = false  # Disable the SASS compiler cache

资产管道拥有自己的缓存实例,设置config.assets.cache = false什么都不做,所以你必须将其缓存设置为null_store才能禁用它。

即使这样,SASS编译器也有自己的缓存,如果你需要禁用它,你必须单独禁用它。

答案 1 :(得分:1)

我创建了以下要点(https://gist.github.com/metaskills/9028312),并发现它是唯一适用于我的方法。

# In config/initializers/sprockets.rb

require 'sprockets'
require 'sprockets/server'

Sprockets::Server.class_eval do

  private

  def headers_with_rails_env_check(*args)
    headers_without_rails_env_check(*args).tap do |headers|
      if Rails.env.development?
        headers["Cache-Control"]  = "no-cache"
        headers.delete "Last-Modified"
        headers.delete "ETag"
      end
    end
  end
  alias_method_chain :headers, :rails_env_check

end

答案 2 :(得分:0)

接受的答案是没有正确执行,并且通过完全禁用缓存会降低开发性能。 回答原始问题,即使未直接包含,也希望更改引用的文件以使资产缓存无效。

解决方案是简单地声明这样的依赖关系,以便sprockets知道缓存应该失效:

# layout.html.erb
<% depend_on Rails.root.join('app').join('views').join('_partial.html.erb') %>
# replace the above with the correct path, could also be relative but didn't try