【问题标题】:Static asset caching on Heroku with Jammit by changing ActionController::Base#page_cache_directory通过更改 ActionController::Base#page_cache_directory 在 Heroku 上使用 Jammit 进行静态资产缓存
【发布时间】:2011-03-05 00:01:51
【问题描述】:

我正在尝试使用 Jammit 为部署在 Heroku 上的 Rails 应用程序打包 CSS 和 JS,由于 Heroku 的只读文件系统,它不能开箱即用。我看到的每个关于如何执行此操作的示例都建议提前构建所有打包的资产文件。由于 Heroku 的基于 Git 的部署,这意味着每次这些文件更改时您都需要对存储库进行单独的提交,这对我来说不是一个可接受的解决方案。相反,我想更改 Jammit 用于将缓存包写入到 #{Rails.root}/tmp/assets(通过更改 ActionController::Base#page_cache_directory)的路径,这在 Heroku 上是可写的。

我不明白的是如何使用缓存文件而不每次都访问 Rails 堆栈,即使使用缓存包的默认路径也是如此。让我解释一下我的意思:

当你使用 Jammit 的帮助器包含一个包时,它看起来像这样:

<%= include_javascripts :application %>

生成这个脚本标签:

<script src="/assets/application.js" type="text/javascript"></script>

当浏览器请求这个 URL 时,实际发生的是它被路由到Jammit::Controller#package,它将包的内容呈现给浏览器,然后将缓存的副本写入#{page_cache_directory}/assets/application.js。这个想法是这个缓存文件建立在第一个请求上,后续请求应该直接为缓存文件提供服务,而不会影响 Rails 堆栈。我查看了 Jammit 代码,但不知道这是怎么发生的。是什么阻止了对 /assets/application.js 的后续请求再次简单地路由到 Jammit::Controller 并且从不使用缓存文件?

我的猜测是,我看不到的某个地方有一个 Rack 中间件,如果文件存在,它会为文件提供服务,如果不存在,则将请求转发给控制器。如果是这样,那代码在哪里?当更改ActionController::Base#page_cache_directory(有效地更改 Jammit 写入缓存包的位置)时,它将如何工作?由于#{Rails.root}/tmp 位于公共文档根目录之上,因此没有映射到该路径的 URL。

【问题讨论】:

    标签: ruby-on-rails heroku jammit


    【解决方案1】:

    好问题!我自己没有设置这个,但这是我一直想要研究的东西,所以你促使我这样做。这是我会尝试的(我很快就会自己试一试,但你可能会打败我)。

    config.action_controller.page_cache_directory = "#{Rails.root}/tmp/page_cache"
    

    现在将您的 config.ru 更改为:

    require ::File.expand_path('../config/environment',  __FILE__)
    run Rack::URLMap.new(
       "/"       => Your::App.new,
       "/assets" => Rack::Directory.new("tmp/page_cache/assets"))
    

    请确保public/assets 中没有任何内容,因为它永远不会被拾取。

    注意事项:

    • 这是针对 Rails 3 的。不确定 Rails 2 下的解决方案。
    • 看起来Rack::Directory 将缓存控制标头设置为 12 小时,因此 Heroku 会将您的资产缓存到 Varnish。不确定 Jammit 是否在其控制器中设置了这个,但即使没有,它也会很快被缓存。
    • Heroku 现在也设置了ENV['TMPDIR'],因此如果您愿意,可以使用它来代替Rails.root + '/tmp'

    【讨论】:

    • 但是请使用 Rails.root.join('tmp')。
    • 这个答案是>2岁。现代解决方案是 Rails 资产管道。 guides.rubyonrails.org/asset_pipeline.html
    • 很多人仍然喜欢 jammit 而不是资产管道,我知道我喜欢。
    【解决方案2】:

    这可能有用,它适用于不同的 gem,但想法是相似的,我正试图让它与普通的资产助手一起工作。

    http://devcenter.heroku.com/articles/using-compass

    不幸的是,如果不修补/重写资产助手模块(类似于耦合意大利面条),让 rails 执行此操作似乎相当困难。

    【讨论】:

      猜你喜欢
      • 2011-09-03
      • 2023-03-04
      • 2011-08-04
      • 1970-01-01
      • 2023-03-26
      • 1970-01-01
      • 2018-05-19
      • 2012-09-02
      • 1970-01-01
      相关资源
      最近更新 更多