2011-02-12 63 views
3

我試圖使用Jammit包裝CSS和JS的Rails應用程序部署在Heroku上,不開箱由於Heroku的工作只讀文件系統。我見過的每個例子都說明了如何做到這一點,建議事先構建所有打包的資產文件。由於Heroku基於Git的部署,這意味着每次更改這些文件時都需要對存儲庫進行單獨的提交,這對我來說不是一個可接受的解決方案。相反,我想改變這種狀況Jammit用來緩存包寫入#{Rails.root}/tmp/assets(通過改變ActionController::Base#page_cache_directory)的路徑,這是在Heroku上寫。靜態資產緩存與Jammit改變的ActionController :: Base的#page_cache_directory

什麼我不明白是怎麼緩存文件將沒有擊中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。

回答

5

好問題!我沒有自己設定,但這是我一直想要研究的內容,所以你促使我這樣做。這就是我會嘗試的(我會很快給自己一槍,但你可能會打敗我)。

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不知道下導軌2.
  • 它看起來像Rack::Directory集緩存控制頭12小時,Heroku的將緩存您的資產光油的解決方案。不知道Jammit是否在其控制器中設置了它,但即使它沒有,它也會很快被緩存。
  • Heroku上還設置ENV['TMPDIR']現在爲好,這樣你就可以,如果你想使用,而不是Rails.root + '/tmp'
+0

但請使用Rails.root.join('tmp')。 –

+0

這個答案是> 2歲。現代的解決方案是Rails資產管道。 http://guides.rubyonrails.org/asset_pipeline.html – wuputah

+0

許多人仍然喜歡jammit到資產管道,我知道我這樣做。 –

0

這可能是有用的,它是一個不同的創業板,但這個想法是相似的,我試圖讓它與普通資產助手一起工作。

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

不幸的是,似乎是相當難以得到軌做到不打補丁/重寫資產助手模塊(它類似於再加麪條)。