【问题标题】:Heroku does NOT compile files under assets pipelines in Rails 4Heroku 不会在 Rails 4 中的资产管道下编译文件
【发布时间】:2013-02-27 13:42:37
【问题描述】:

在本地机器上一切顺利,在 Rails 4 和 Ruby 2.0 中使用资产管道。但是部署到heroku时,显示:

-----> Preparing app for Rails asset pipeline
   Running: rake assets:precompile
   I, [2013-03-12T03:28:29.908234 #912]  INFO -- : Writing /tmp/build_1n6yi8lwna3sj/public/assets/rails-2ee5a98f26fbf8c6c461127da73c47eb.png
   I, [2013-03-12T03:28:29.914096 #912]  INFO -- : Writing /tmp/build_1n6yi8lwna3sj/public/assets/trash-3c3c2861eca3747315d712bcfc182902.png
   I, [2013-03-12T03:28:33.963234 #912]  INFO -- : Writing /tmp/build_1n6yi8lwna3sj/public/assets/application-bf2525bd32aa2a7068dbcfaa591b3874.js
   I, [2013-03-12T03:28:40.362850 #912]  INFO -- : Writing /tmp/build_1n6yi8lwna3sj/public/assets/application-13374a65f29a3b4cea6f8da2816ce7ff.css
   Asset precompilation completed (14.36s)

Heroku 似乎可以编译文件,但将其放在 /tmp 中没有任何错误。我的问题是:

  1. Heroku 是如何将资产文件编译到 /tmp 的?
  2. 我的最后一个解决方案是在本地运行 RAILS_ENV=production bundle exec rake assets:precompile,但这会在 public/assets 中生成 manifest-xxxxxx.json,而不是 manifest.yml,因此 heroku 不会检测到 JSON 清单文件。我通过从 json 文件手动创建一个 yml 来整理它,heroku 变得很高兴。 heroku 的方法已经过时了吗?

【问题讨论】:

  • 1) 有人正在调查此问题
  • 2) 在 rails 4 中发生了变化,对 buildpack 有一个拉取请求来更新它
  • @ctshryock 对此有何更新?
  • 清单问题有github.com/heroku/heroku-buildpack-ruby/pull/74。我今天会在 /tmp/ 问题上向人们发出问题,现在还在发生,对吗?
  • @ctshryock 是的,不幸的是它仍在发生...感谢您的适当贡献...

标签: heroku asset-pipeline ruby-on-rails-4


【解决方案1】:

这可能无法回答原始问题的根本原因,但我有类似的症状,但根本原因不同。

JPEG 文件的预编译会将文件扩展名更改为 JPG,这意味着 asset_path("my_image.jpeg")asset_path("my_image") 不起作用。从 JPEG 中删除“e”,瞧,它可以工作了。

其他人在这里描述了同样的问题https://blazarblogs.wordpress.com/2016/04/06/rails-force-to-precompile-jpeg-to-jpg/

这是一个错误吗?还是期望的行为?而且奇怪的是它只在我的 Heroku 托管的生产环境中不起作用。也许他们有某种配置。

【讨论】:

    【解决方案2】:

    添加这个宝石gem 'rails_serve_static_assets'

    https://github.com/heroku/rails_serve_static_assets

    【讨论】:

      【解决方案3】:

      使用图片扩展

      我遇到了同样的问题,但原因不同。

      代替

      <%= asset_path 'facebook-link' %>
      

      用途:

      <%= asset_path 'facebook-link.png' %>
      

      虽然第一个在本地工作,但当我推送到 Heroku 时,我的图像坏了,我不知道为什么。使用完整的文件扩展名解决了问题:)

      【讨论】:

        【解决方案4】:

        在 Rails 4.2.4 中,您的 production.rb 有一行:

        config.serve_static_files = ENV['RAILS_SERVE_STATIC_FILES'].present?
        

        这意味着,gem 'rails_12factor', group: :production 不需要将其更改为 true,因为它可以通过 heroku 环境变量进行设置。如果您删除 rails_12factor gem,您也会收到警告。

        如果您有problems with assets,请登录heroku 控制台heroku run rails console 并找出文件puts helper.asset_path("application.js") 的资产路径。

        当未提供文件结尾时,我注意到开发和生产之间的一个奇怪行为:

        对于图像/assets/images/image_01.jpgasset_paths的以下输出不同:

        发展

        development > puts helper.asset_path('profile_01') 
        => /assets/profile_01-bbd16aac5ef1d295411af44c103fcc631ab90ee94957414d4c01c3aed1055714.jpg
        
        development > puts helper.asset_path('profile_01.jpg') 
        => /assets/profile_01-bbd16aac5ef1d295411af44c103fcc631ab90ee94957414d4c01c3aed1055714.jpg
        

        生产

        development > puts helper.asset_path('profile_01') 
        => /profile_01
        
        development > puts helper.asset_path('profile_01.jpg') 
        => /assets/profile_01-bbd16aac5ef1d295411af44c103fcc631ab90ee94957414d4c01c3aed1055714.jpg
        

        您确实不必运行RAILS_ENV=production rake assets:precompile,heroku 在部署期间会为您执行此操作。此外,您不必在开发中预编译资产并将它们推送到 heroku。

        【讨论】:

          【解决方案5】:

          您需要配置 Rails 以在生产环境中提供静态资源:config/environments/production.rb

          SampleApp::Application.configure 做 . . . config.serve_static_assets = true . . . 结尾

          更新:

          在 Rails 4 中已弃用,并已更改为:

          config.serve_static_files = true 
          

          【讨论】:

          • 我还必须删除我的 public/assets 文件夹,因为这些文件夹是我团队中的其他人在本地预编译的,检查到 GitHub 并覆盖了 Heroku 的资产编译过程。
          【解决方案6】:

          除了确保安装了“rails_12factor”gem 之外,您唯一需要做的就是这个。

          # config/application.rb
          
          config.assets.paths << Rails.root.join('vendor', 'assets')
          

          似乎尽管 Rails 确切地知道它想要什么,但 Heroku 需要提醒将 assets 文件夹包含在 assets 路径中。

          【讨论】:

            【解决方案7】:

            我想我会添加这个作为答案,因为如果你搜索 "assets",这个问题是从 Heroku 支持页面链接的。

            这主要适用于将他们的应用程序更新到 Rails 4 的人,但是在经历了这个 - 以及许多其他 SO 帖子之后 - 最终让我改变了 production.rb 中的以下内容:

            config.action_dispatch.x_sendfile_header = "X-Sendfile"
            

            收件人:

            config.action_dispatch.x_sendfile_header = nil
            

            我在升级时没有发现这个问题,而且像往常一样,我花了很长时间才弄明白。希望它可以帮助别人!向PatrickEm 大声喊叫,他在question 中提出/回答了同样的问题。

            【讨论】:

              【解决方案8】:

              我需要使用这个 gem:

              gem 'rails_12factor', group: :production #need this for rails 4 assets on heroku
              

              在 /config/environments/production.rb 我需要设置:

              config.assets.compile = true
              

              我的理解是rails_12_factor gem 设置config.serve_static_assets = true 等等。

              【讨论】:

                【解决方案9】:

                如果您正在使用控制器特定资产,如下所示:

                 <%= javascript_include_tag params[:controller] %> or <%= javascript_include_tag params[:controller] %>
                

                然后在生产中,您将需要显式地预编译这些文件(在开发中,rails 会即时编译文件)。

                在此处查看官方 Rails 指南:http://guides.rubyonrails.org/asset_pipeline.html#controller-specific-assets

                要按照指南中的说明进行预编译(此处:http://guides.rubyonrails.org/asset_pipeline.html#precompiling-assets),您需要将以下内容添加到 config/application.rb

                # config/application.rb
                config.assets.precompile << Proc.new do |path|
                  if path =~ /\.(css|js)\z/
                    full_path = Rails.application.assets.resolve(path).to_path
                    app_assets_path = Rails.root.join('app', 'assets').to_path
                    if full_path.starts_with? app_assets_path
                      puts "including asset: " + full_path
                      true
                    else
                      puts "excluding asset: " + full_path
                      false
                    end
                  else
                    false
                  end
                end
                

                【讨论】:

                  【解决方案10】:

                  我将此添加到 assets/stylesheets/ 文件夹中我的一个 css.scss 文件的顶部。

                  @import "font-awesome";
                  

                  然后跑了..

                  rake assets:clean
                  

                  还有……

                  rake assets:precompile RAILS_ENV=production
                  

                  【讨论】:

                    【解决方案11】:

                    经过几个小时的谷歌搜索,Heroku 上的指南或 StackOverFlow 上的建议都没有帮助我,我终于遇到了this blog post,它提供了这个线索:

                    heroku labs:enable user-env-compile --app=YOUR_APP
                    

                    如果没有这个,资产管道将始终尝试初始化整个应用程序并连接到数据库(尽管您可能已经阅读过 Rails 4 现在不再这样做了)。这会将您的 Heroku 配置暴露给 Rails,因此它可以成功启动并运行诸如 assets:precompile 之类的 rake 任务。

                    【讨论】:

                    • 终于成功了。它说这个功能是实验性的,可以随时删除。
                    • "没有这样的功能:user-env-compile"
                    • 它不再是实验室功能,而是默认包含在 Heroku 堆栈中。不再需要运行此命令。
                    【解决方案12】:

                    在我的例子中,资产是按照上面的说明编译的,但它没有选择引导 glyphicons 'fontawesome-webfont',所以在浪费了这么多时间研究之后,这终于对我有用了。

                    宝石文件

                    gem 'rails_12factor', group: :production
                    

                    捆绑安装

                    config/application.rb

                    config.assets.precompile += %w(*.png *.jpg *.jpeg *.gif,
                                                      "fontawesome-webfont.ttf",
                                                     "fontawesome-webfont.eot",
                                                     "fontawesome-webfont.svg",
                                                     "fontawesome-webfont.woff")
                    
                    
                    
                    config.assets.precompile << Proc.new do |path|
                          if path =~ /\.(css|js)\z/
                            full_path = Rails.application.assets.resolve(path).to_path
                            app_assets_path = Rails.root.join('app', 'assets').to_path
                            if full_path.starts_with? app_assets_path
                              puts "including asset: " + full_path
                              true
                            else
                              puts "excluding asset: " + full_path
                              false
                            end
                          else
                            false
                          end
                        end
                    

                    环境/生产.rb

                    config.serve_static_assets = true
                    

                    最后,我跑了 rake assets:precompile RAILS_ENV=production 并将其推送到 heroku 并且成功了。

                    【讨论】:

                    • 我相信 rails_12factor 完成了 config.serve_static_assets 部分。
                    【解决方案13】:

                    Heroku 的资产插件不再工作,因为 Rails 4 不支持插件。您需要改用 Heroku 的资产宝石。把它放在你的 Gemfile 中:

                    group :production do
                      gem 'rails_log_stdout',           github: 'heroku/rails_log_stdout'
                      gem 'rails3_serve_static_assets', github: 'heroku/rails3_serve_static_assets'
                    end
                    

                    关注Heroku's guide,开始使用 Rails 4。

                    更新 (07/22/2013):Heroku 现在提供不同的 gem 来预编译资产。

                    group :production do
                      gem 'rails_12factor'
                    end
                    

                    【讨论】:

                    • 这对我来说不是必需的。只需按照@Israel Barba 的回答将config.serve_static_assets = false 更改为true
                    • 我以前是这样做的,但我相信如果你这样做,你必须预编译资产并自己提交它们。这仍然正确吗?
                    • 它在没有预编译的情况下工作。可能有一种情况我没有注意到它不起作用(我只有一个简单的样式表)
                    • 这不起作用。预编译也不行。对我们来说,heroku 上的 rails 4 资产管道中断了,我们浪费了大量时间,回到 ec2 - grumble grumble。
                    • 您是否在 CSS 和其他地方使用了asset_path() 助手?通过“/assets/filename.jpg”引用资产在 Heroku 上也不起作用。
                    【解决方案14】:

                    由于rails 4 replaced manifest.yml with manifest-(fingerprint).json,您需要启用静态资产服务。

                    来自Getting Started with Rails 4.x on Heroku

                    gem 'rails_12factor', group: :production
                    

                    然后

                    bundle install
                    

                    最后,

                    git push heroku
                    

                    为我解决了这个问题。希望这会有所帮助!

                    【讨论】:

                    • 官方文档上是这么说的,但是对别人有用吗?我的 gemfile 上有这个,而且 javascript 文件似乎仍然没有预编译
                    • 我已经完成了一切:gem 'rails_12factor', group: :production config.serve_static_assets = true config.assets.precompile += %w( *.css *.js ) 我有我的 js 和 css供应商/资产/下的文件。当我部署到 heroku 时,一切看起来都很好: 运行:rake assets:precompile 资产预编译完成(310.44s)当我看到 application-5c84e59d83c00fd13fb659edc18db24a.js 时,它都是空的你知道我做错了什么吗?
                    • 这对我不起作用。 config.serve_static_assets = true 表示 css 开始正确服务,但不是图像或 JS。
                    • 这对我有用,感谢@voss 提供更新的答案。 Heroku 已将 rails_log_std_out 和 rails3_serve_static_assets 替换为 rails_12factor。
                    • 你是如何引用你的图片的?我试过 background-image:url('/public/assets/starsw600.jpg');只是('starsw600.jpg')。尚未尝试与 config.serve_static_assets 和 ('starsw60xxxxxx.jpg) 的所有组合。
                    【解决方案15】:

                    这是 Heroku Ruby Buildpack 的一个问题,但今天(2013-05-21)部署了更新。请尝试一下并告诉我们。

                    回答您的问题:

                    #1) 这是链轮输出;东西被编译到/tmp,然后移动(见here in Sprockets)。据我所知,这一直是这样做的,但直到 Sprockets 版本在 Rails 中更新后,我们才获得了这个新的调试类型输出。

                    #2) 以前assets:precompile 生成了一个manifest.json 文件,但现在在Rails 4 中,清单文件中有一个指纹,这是以前没有检测到的。这已通过#74 修复。

                    【讨论】:

                      【解决方案16】:

                      我遇到了完全相同的问题。

                      我在环境/production.rb 文件中设置了 config.serve_static_assets = true,直到 heroku 不支持新的清单格式。

                      因此,在添加 heroku 支持之前,这是一个临时解决方案。

                      【讨论】:

                      • 那行不通。 Heroku 注入 this 正是这样做的:即它不起作用,目前最好的解决方案:将 manifest.json 复制到 manifest.yml(无需转换)以欺骗 heroku 检测预编译资产.
                      • 如果你提供静态资源,它可以工作,但它不适用于所有拥有自己资源的 gem,比如 Font Awesome 或 HTML5 Boilerplate。
                      • @dakull 的工作原理是它现在可以正确地为 JS 文件提供服务,但仍然无法提供 app/assets/images 目录中的背景图像纹理。
                      猜你喜欢
                      • 1970-01-01
                      • 2013-07-30
                      • 1970-01-01
                      • 2014-03-08
                      • 1970-01-01
                      • 2013-05-29
                      • 1970-01-01
                      • 2014-08-28
                      • 2014-06-27
                      相关资源
                      最近更新 更多