【问题标题】:Why are my Rails assets getting precompiled twice?为什么我的 Rails 资源会被预编译两次?
【发布时间】:2013-03-13 19:10:33
【问题描述】:

我注意到我的资产似乎被编译了两次,这大大减慢了我的部署速度,因为这一步是最耗时的部分:

~/projects/rewportal(mapwidget ✔) rake assets:precompile
/home/ruy/.rvm/rubies/ruby-1.9.3-p194/bin/ruby /home/ruy/.rvm/gems/ruby-1.9.3-p194@rewportal/bin/rake assets:precompile:all RAILS_ENV=production RAILS_GROUPS=assets
AssetSync: using /home/ruy/projects/rewportal/config/initializers/asset_sync.rb
AssetSync: using /home/ruy/projects/rewportal/config/initializers/asset_sync.rb
AssetSync: Syncing.
Using: Directory Search of /home/ruy/projects/rewportal/public/assets
Uploading: assets/application-5170f52c1dd49cb382d5135bee01d75e.js
[...]
Fetching files to flag for delete
Flagging 8 file(s) for deletion
Deleting: assets/active_admin-4ce46d089d4b0080e87c9abcb6fa6c97.css
[...]
AssetSync: Done.

这正常吗?

当我预编译到其他环境(非生产)时,我可以两次看到每个资产的详细编译:

~/projects/rewportal(mapwidget ✔) rake RAILS_ENV=qa assets:precompile --trace
** Invoke assets:precompile (first_time)
** Execute assets:precompile
/home/ruy/.rvm/rubies/ruby-1.9.3-p194/bin/ruby /home/ruy/.rvm/gems/ruby-1.9.3-p194@rewportal/bin/rake assets:precompile:all RAILS_ENV=qa RAILS_GROUPS=assets --trace
** Invoke assets:precompile:all (first_time)
** Execute assets:precompile:all
** Invoke assets:precompile:primary (first_time)
** Invoke assets:environment (first_time)
** Execute assets:environment
AssetSync: using /home/ruy/projects/rewportal/config/initializers/asset_sync.rb
** Invoke tmp:cache:clear (first_time)
** Execute tmp:cache:clear
** Execute assets:precompile:primary
Compiled gmaps4rails/gmaps4rails.base.js  (141ms)  (pid 8480)
Compiled gmaps4rails/gmaps4rails.googlemaps.js  (148ms)  (pid 8480)
[...]
Compiled active_admin.css  (1299ms)  (pid 8480)
Compiled active_admin/print.css  (113ms)  (pid 8480)
** Invoke assets:precompile:nondigest (first_time)
** Invoke assets:environment (first_time)
** Execute assets:environment
AssetSync: using /home/ruy/projects/rewportal/config/initializers/asset_sync.rb
** Invoke tmp:cache:clear (first_time)
** Execute tmp:cache:clear
** Execute assets:precompile:nondigest
Compiled gmaps4rails/gmaps4rails.base.js  (133ms)  (pid 8480)
Compiled gmaps4rails/gmaps4rails.googlemaps.js  (133ms)  (pid 8480)
[...]
Compiled active_admin.css  (1290ms)  (pid 8480)
Compiled active_admin/print.css  (116ms)  (pid 8480)
AssetSync: Syncing.
Using: Directory Search of /home/ruy/projects/rewportal/public/assets
Uploading: assets/active_admin-d05b61ab8366b74eabc9074d3e60fe82.css.gz
[...]
Fetching files to flag for delete
Flagging 6 file(s) for deletion
Deleting: assets/active_admin-ec90e7d9a9f45f14d1387f58fa1452b4.css
[...]
AssetSync: Done.

我的application.rb 有以下内容:

config.assets.precompile += %w( active_admin/print.css active_admin.css active_admin.js admin.js admin.css html5shiv.js )

想法?

【问题讨论】:

  • 我觉得这不正常。尝试在本地主机上使用 foreman start
  • 所以它似乎不是 Heroku 特有的。我跑了rake assets:precompile,它也跑了两次。我会更新标题和详细信息。
  • 有完全相同的问题。一切正常,但运行两次似乎很浪费。
  • active_admin 中有一个初始化器,将其资产文件添加到预编译列表中;也许您在application.rb 中添加的行是重复的。如果你把它注释掉会发生什么?
  • 这是正常的。预编译任务首先将您的资产编译成主要格式,然后编译成摘要格式(即使用 MD5 指纹)。

标签: ruby-on-rails asset-pipeline activeadmin


【解决方案1】:

默认情况下,Rails 3 编译一次生成指纹资产,一次生成非指纹资产(指纹资产在文件名中有 MD5 哈希)。

您可以使用turbo-sprockets-rails3 gem 从一个编译中创建两者。

在 Rails 4 中,此功能被提取到 sprockets-rails gem 中并更改了行为,因此在 Rails 4 中不会发生双重编译。

【讨论】:

    【解决方案2】:

    你在使用 capistrano 吗?如果是这样,你可以尝试在本地编译你的资产,然后上传到服务器,像这样的任务

    namespace :deploy do
      namespace :assets do
        desc "Precompile assets on local machine and upload them to the server."
        task :precompile, roles: :web, except: {no_release: true} do
          run_locally "bundle exec rake assets:precompile"
          find_servers_for_task(current_task).each do |server|
            run_locally "rsync -vr --exclude='.DS_Store' public/assets #{user}@#{server.host}:#{shared_path}/"
          end
        end
      end
    end
    

    【讨论】:

      【解决方案3】:

      我在上传前覆盖了 deploy.rb 中的 deploy_all 任务进行编译:

      task :remake_all do
        puts "precompiling assets"
        res = `env rake assets:precompile:all RAILS_ENV=precompile RAILS_GROUPS=assets 2>&1`
      
        $stderr.puts "assets res is: #{res}"
        if res =~ /aborted|don't|invalid|segmentation|bug/i
          puts "############  Unable to compile assets  #########" 
          exit
        end
      end
      

      我遇到了开发环境无法正确编译和生产环境需要访问防火墙后面的 mysql 服务器的问题,因此创建了一个名为 :precompile 的新环境

      【讨论】:

        【解决方案4】:

        我的解决方案(Rails 3)是运行 rake assets:precompile:primary 而不是 rake assets:precompile:all

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-04-07
          • 1970-01-01
          • 1970-01-01
          • 2011-02-25
          • 1970-01-01
          • 1970-01-01
          • 2020-04-08
          • 2013-08-03
          相关资源
          最近更新 更多