アセットを s3 でホストしています。本番環境では、Rails は /javascripts/cache/all.js と /stylesheets/cache/all.css を探します。cap でデプロイするときに、プラグインを使用して public ディレクトリを s3 に急降下させています。問題は、レールが最初に要求されるまでこれらのキャッシュ ファイルを作成しないため、パブリック ディレクトリを転送するときに展開中に存在しないことです。展開中にこれらのファイルを強制的に作成する簡単な方法はありますか?
5 に答える
キャッシュ ファイルを作成する実際の Rails モジュールは、ActionView::Helpers::AssetTagHelper
展開中にキャッシュ ファイルを作成するために再利用できる可能性があります。以下は私にとってはうまくいきました:
require 'action_view'
class AssetCacheWriter
include ActionView::Helpers::AssetTagHelper
def write
write_asset_file_contents(File.join(JAVASCRIPTS_DIR, "all.js"), compute_javascript_paths([:all], true))
write_asset_file_contents(File.join(STYLESHEETS_DIR, "all.css"), compute_stylesheet_paths([:all], true))
'standard_all')
end
end
これらのwrite_asset_file_contents
呼び出しは両方とも、Rails コードから削除しました。_DIR
定数は含まれるモジュールで定義され、呼び出しのパラメーターtrue
は、compute_xxx_paths
すべてのファイルを再帰的に含める必要があることを示します。
ファイルを書き出すだけの単純な cap タスクを作成しました。
namespace :sample
task :assets do
AssetCacheWriter.new.write
end
end
これをrakeタスクファイルで使用します。追加のクラスを作成する手間を省き、DRY のままにします。stylesheet_link_tag / javascript_include_tag
desc "Clears javascripts/cache and stylesheets/cache" task :clear => :environment do
puts "Clearing javascripts/cache and stylesheets/cache"
FileUtils.rm(Dir['public/javascripts/cache_[^.]*']) # use :cache => 'cache_all.js' in stylesheet_link_tag
FileUtils.rm(Dir['public/stylesheets/cache_[^.]*']) # use :cache => 'cache_all.css' in javascript_include_tag
end
desc "Recreate the javascripts/stylesheets cache."
task :generate => [:environment, :clear] do
puts "Recreate the javascripts/stylesheets cache"
ActionController::Base.perform_caching = true
app = ActionController::Integration::Session.new
app.get '/'
end
Engine Yard Cloud を使用している場合は、次のようにします。
ファイル /lib/tasks/assetcache.rake を追加しました
require 'assetwriter'
namespace :assetcache do
desc "Clears javascripts/cache and stylesheets/cache"
task :clear => :environment do
puts "Clearing javascripts/cache and stylesheets/cache"
FileUtils.rm(Dir['public/javascripts/cache_[^.]*'])
# use :cache => 'cache_all.js' in stylesheet_link_tag
FileUtils.rm(Dir['public/stylesheets/cache_[^.]*'])
# use :cache => 'cache_all.css' in javascript_include_tag
end
desc "Recreate the javascripts/stylesheets cache."
task :generate => [:environment, :clear] do
puts "Recreate the javascripts/stylesheets cache"
AssetCacheWriter.new.write
end
end
次に /lib/assetwriter.rb を追加しました
「action_view」クラスの AssetCacheWriter が必要です
ActionView::Helpers::AssetTagHelper を含める
def write write_asset_file_contents(File.join(JAVASCRIPTS_DIR, "cache/all.js"), compute_javascript_paths([:all], true)) write_asset_file_contents(File.join(STYLESHEETS_DIR, "cache/all.css"), compute_stylesheet_paths([:すべて]、true)) 終了
終わり
次に、 /deploy/after_restart.rb に追加しました
「cd #{release_path} && bundle exec rake assetcache:generate」を実行します
Rails 3.0.7では、上記のアプローチはどれも機能していないようです。構成が未定義であるというエラーが多数発生しました。
Railsコードを見て手を汚した後、私は自分に合ったこのソリューションを思いつきました。
lib / tasks / cache_assets.rake
require 'asset_packager'
desc "cache assets"
task :cache_assets do
puts "-----> Caching Assets"
AssetCacheWriter.new.write
puts "-----> Done!"
end
そして、lib /asset_packager.rb
require 'action_view'
class AssetCacheWriter
include ActionView::Helpers::AssetTagHelper
include ActionView::Helpers::TagHelper
def config
ApplicationController
end
def controller
ApplicationController
end
def write
ActionController::Base.perform_caching = true
# You can replace these with your app's cached assets. They should look the same
# as in your view templates.
stylesheet_link_tag :vendor, :defaults, :cache => 'cached/all'
javascript_include_tag :bd_defaults, :'vendor-head', :cache => 'cached/defaults_vendor'
end
end
次に、それを実行するには、実行するだけですrake cache_assets
インクルードの順序が重要であることがわかり (たとえば、jQuery は他のスクリプトの前にインクルードされます)、代わりに以下のアプローチを使用しました。:defaults の使用も許可します。
最初の lib/asset_packager:
require 'action_view'
class AssetCacheWriter
include ActionView::Helpers::AssetTagHelper
include ActionView::Helpers::TagHelper
def write
ActionController::Base.perform_caching = true
stylesheet_link_tag *ApplicationController::STYLESHEET_INCLUDES
javascript_include_tag *ApplicationController::JAVASCRIPT_INCLUDES
end
end
次に、scripts/package_assets:
#!/usr/bin/env ruby
RAILS_ROOT = File.expand_path(File.dirname(__FILE__) + '/../')
Dir.chdir(RAILS_ROOT)
RAILS_ENV = ENV['RAILS_ENV'] || 'development'
puts "Bundling assets for environment #{RAILS_ENV}"
require File.join('config', 'environment')
AssetCacheWriter.new.write
次にキャップタスク:
desc "Package assets"
task :package_assets do
%x[#{Dir.getwd}/script/package_assets]
%x[svn commit #{Dir.getwd}/public/javascripts/defaults.js #{Dir.getwd}/public/stylesheets/defaults.css -m "(capistrano) packaging assets to trunk"]
logger.info "packaged assets to trunk"
end