【问题标题】:Forcing rails to create asset cache files强制 rails 创建资产缓存文件
【发布时间】:2009-06-11 21:33:18
【问题描述】:

我在 s3 上托管我的资产。在生产环境中,rails 正在寻找 /javascripts/cache/all.js 和 /stylesheets/cache/all.css。当我使用 cap 进行部署时,我正在使用插件将公共目录转移到 s3。问题是 Rails 在第一次请求它们之前不会创建这些缓存文件,因此当我传输公共目录时,它们在部署期间并不存在。有没有一种简单的方法可以在部署期间强制创建这些文件?

【问题讨论】:

    标签: ruby-on-rails capistrano deployment asset-management


    【解决方案1】:

    创建缓存文件的实际 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 常量在包含的模块中定义,compute_xxx_paths 调用中的true 参数表明所有文件都应递归包含。

    我创建了一个简单的 cap 任务,只是将文件写出来:

    namespace :sample
      task :assets do
        AssetCacheWriter.new.write
      end
    end
    

    【讨论】:

      【解决方案2】:

      我在 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
      

      【讨论】:

        【解决方案3】:

        如果您使用的是 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

        定义写入 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([:all], true)) 结束

        结束

        然后我添加到 /deploy/after_restart.rb

        运行“cd #{release_path} && bundle exec rake assetcache:generate”

        【讨论】:

          【解决方案4】:

          我发现包含顺序很重要(例如,jQuery 在其他脚本之前包含在内),因此改用以下方法。还允许使用 :defaults。

          第一个 lib/asset_pacakger:

          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
          

          然后是脚本/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
          

          【讨论】:

            【解决方案5】:

            在 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

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2017-03-15
              • 2013-04-01
              • 2011-10-04
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2019-01-18
              相关资源
              最近更新 更多