在开发中禁用 Sprockets 资产缓存

17

我正在使用Rails 3.2.13 和 Rails 资源管道(Asset Pipeline)。 我想要使用资源管道,这样我就可以在我的资产中使用SASS和CoffeeScript以及ERB,并使管道自动编译它们,因此我不能在开发过程中关闭管道。 我从未在开发过程中预编译资源,甚至没有public/assets/目录。

然而,当我更改一个包含的文件时,例如一个被包含(呈现)在layout.html.erb文件中的_partial.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 Asset Pipeline指南的整个缓存工作原理部分只有以下内容:

Sprockets使用默认的Rails缓存存储器在开发和生产环境下缓存资源。

TODO:添加更多关于更改默认存储器的信息。

那么,我该如何让Sprockets在需要时编译资产但不缓存结果?

3个回答

30

这是神奇的咒语:

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

资产管道(asset pipeline)有自己的缓存实例,设置config.assets.cache = false不起作用,因此您需要将其缓存设置为null_store来禁用它。

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


这真的让我筋疲力尽,每次测试操作缓存逻辑时都必须打开/关闭文件存储缓存(没有实际缓存部分)。谢谢。 - CrazyVipa
这适用于Rails 4上的第一个请求,随后的请求将缓存在tmp/cache中(位于Rails根目录下,而不是/tmp)。如果您清除tmp/cache,则会重新构建。我想知道如何完全禁用tmp/cache? - Cymen
2
@Cymen,在Rails 4中,缓存的工作方式有所不同。如果你想获得帮助,请发布一个新的问题。 - Old Pro
4
@OldPro 很好的观点 -- 我想大多数人都是通过 Google 找到这里的,但还是不妨去做一下:https://dev59.com/mn7aa4cB1Zd3GeqPr5GN - Cymen
它看起来确实是一个错误,你是否已经报告了这个问题? - brauliobo

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

缓存问题我也遇到了,通过浏览器缓存重置解决了。 - brauliobo

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接