我正在尝试使用 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。