【问题标题】:Rails 4: assets not loading in productionRails 4:资产未在生产中加载
【发布时间】:2013-09-13 01:25:25
【问题描述】:

我正在尝试将我的应用程序投入生产,但图像和 css 资产路径无法正常工作。

这是我目前正在做的事情:

  • 图片资源位于 /app/assets/images/image.jpg
  • 样式表位于 /app/assets/stylesheets/style.css 中
  • 在我的布局中,我引用了这样的 css 文件:<%= stylesheet_link_tag "styles", media: "all", "data-turbolinks-track" => true %>
  • 在重启独角兽之前,我运行RAILS_ENV=production bundle exec rake assets:precompile,它成功了,我在public/assets目录中看到了指纹文件。

当我浏览我的网站时,我收到 mysite.com/stylesheets/styles.css 的 404 not found 错误。

我做错了什么?

更新: 在我的布局中,它看起来像这样:

<%= stylesheet_link_tag    "bootstrap.min", media: "all", "data-turbolinks-track" => true %>
<%= stylesheet_link_tag    "styles", media: "all", "data-turbolinks-track" => true %>
<%= javascript_include_tag "application", "data-turbolinks-track" => true %>

生成源是这样的:

<link data-turbolinks-track="true" href="/stylesheets/bootstrap.min.css" media="all" rel="stylesheet" />
<link data-turbolinks-track="true" href="/stylesheets/styles.css" media="all" rel="stylesheet" />
<script data-turbolinks-track="true" src="/assets/application-0c647c942c6eff10ad92f1f2b0c64efe.js"></script>

Rails 似乎没有正确查找编译后的 css 文件。但它非常令人困惑为什么它在 javascripts 中正常工作(注意 /assets/****.js 路径)。

【问题讨论】:

  • 你能告诉我们你是如何加载你的css文件的吗?从您的错误看来,您尝试硬链接它而不是使用stylesheet_link_tag
  • 刚刚添加到上面。我在做&lt;%= stylesheet_link_tag "style", media: "all", "data-turbolinks-track" =&gt; true %&gt;
  • 好的,所以我会推荐两件事:1. 如果此行被写为public/assets 的路径,请检查生成的源代码;以及 2. 仔细检查是否没有其他指令试图加载它css 文件(可能是硬编码的)
  • 我不能说使用 .erb 是否有问题,因为我从不这样做:.home {background: #FFF url(&lt;%= image_path 'hippopotamus.jpg' %&gt;) no-repeat; } 实际上可以在 sprocket 中替换为 .home {background: #FFF url(image-path('hippopotamus.jpg')) no-repeat; }。如果这有帮助,也许你可以试试。
  • 您是说我可以在我的 css 文件中动态引用该引用而不添加 .erb 扩展名?我更改了它,因为我不希望在我处于开发模式时链接断开。

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


【解决方案1】:

Rails 4 不再生成资产的非指纹版本:不会为您生成 stylesheets/style.css。

如果您使用stylesheet_link_tag,则会生成指向您的样式表的正确链接

另外styles.css 应该在config.assets.precompile 中,这是预编译的东西的列表

【讨论】:

  • 我在 /public/assets/ 目录中看到了指纹文件。在我的布局中,我有这个:&lt;%= stylesheet_link_tag "styles", media: "all", "data-turbolinks-track" =&gt; true %&gt; 这是不正确的吗?`
  • 由于某种原因,当我查看源代码时,生产部署仍然指向原始文件&lt;link data-turbolinks-track="true" href="/stylesheets/bootstrap.min.css" media="all" rel="stylesheet" /&gt;但是javascript文件是正确的!我不明白为什么相同的配置适用于 .js 文件而不适用于 .css。
  • 在 Rails 5.0.0.beta3 上我收到此警告:弃用警告:serve_static_files 已弃用,将在 Rails 5.1 中删除。请改用public_file_server.enabled = true
  • @emersonthis 一样! Js 加载完美,但一些 css 文件得到404。你解决了吗?
  • 资产管道配置几乎总是有问题。如果您在任何非默认位置有文件,那几乎肯定是问题所在,您需要使用第一个答案之类的方式告诉资产管道。
【解决方案2】:

/config/environments/production.rb 我必须添加这个:

Rails.application.config.assets.precompile += %w( *.js ^[^_]*.css *.css.erb )

.js 已经被预编译了,但我还是添加了它。 .css 和 .css.erb 显然不会自动发生。 ^[^_] 排除了部分编译——它是一个正则表达式。

有点令人沮丧的是,文档明确指出默认启用资产管道,但没有阐明仅适用于 javascripts 的事实。

【讨论】:

  • 需要在config.assets.precompile中添加styles.css
【解决方案3】:

我能够通过更改来解决这个问题: config.assets.compile = false
config.assets.compile = true/config/environments/production.rb

更新(2018 年 6 月 24 日):如果您使用的 Sprocket 版本低于 2.12.5、3.7.2 或 4.0.0.beta8,此方法会创建 a security vulnerability

【讨论】:

  • 这是否意味着 Rails 正在编译资产,而不是从 CDN 加载它们?
  • @BenjaminOakes 是的,这就是我想要的
  • 此模式使用更多内存,性能比默认更差,不推荐使用。最好使用 nginx 代理。
【解决方案4】:

在 Rails 4 中,您需要进行以下更改:

config.assets.compile = true
config.assets.precompile =  ['*.js', '*.css', '*.css.erb'] 

这对我有用。使用以下命令预编译资产

RAILS_ENV=production bundle exec rake assets:precompile

祝你好运!

【讨论】:

  • 我认为将 config.assets.compile 设置为 true 会降低生产性能。还有,css.erb?谁用它?萨斯和咖啡呢?
  • 当请求 coffee 和 sass 文件时,它们由 coffee-script 和 sass-rails gems 提供的处理器处理,然后分别作为 JavaScript 和 CSS 发送回浏览器。
  • Rails 4 已经解决了这个问题,所以不需要使用 turbo-sprocket-rails3 gem
  • 抱歉,我无法将您回答我的问题的内容联系起来。
  • 通常,当您运行生产服务器时,您将在 Apache 或 nginx 网络服务器后面运行带有乘客或独角兽或美洲狮的 Rails。最好让 Apache 或 nginx 服务静态文件(js、css、图像),而 Rails 应用服务器(puma、unicorn)服务 Rails 代码和模板。为此,您应该关闭config.serve_static_files,并在Apache和nginx中配置别名来处理assets
【解决方案5】:

我刚遇到同样的问题,在 config/environments/production.rb 中找到了这个设置:

# Rails 4:
config.serve_static_assets = false

# Or for Rails 5:
config.public_file_server.enabled = false

将其更改为 true 即可正常工作。默认情况下,Rails 似乎希望您已将前端 Web 服务器配置为处理公共文件夹外的文件请求,而不是将它们代理到 Rails 应用程序。也许您已经为您的 javascript 文件而不是您的 CSS 样式表做到了这一点?

(See Rails 5 documentation)。如 cmets 中所述,在 Rails 5 中,您可以只设置 RAILS_SERVE_STATIC_FILES 环境变量,因为默认设置是 config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present?

【讨论】:

  • 弃用警告:配置选项 config.serve_static_assets 已重命名为 config.serve_static_files 以阐明其作用(它仅支持为 public 文件夹中的所有内容提供服务,并且与资产管道无关)。 serve_static_assets 别名将在 Rails 5.0 中删除。请相应地迁移您的配置文件。
  • 早些时候当我面临这个问题时,改变那条线已经为我解决了它,但现在我又面临它了(我不知道我是如何一直在这些情况下结束的。)而且这个还不够。关于可能出了什么问题还有什么建议吗?
  • 这应该是公认的答案。虽然它是 Rails 4.2 中的 config.serve_static_files 和 Rails 5 中的 config.public_file_server.enabled。 @见github.com/heroku/rails_serve_static_assets/blob/master/lib/…
  • Rails 5.0.0.1 config/environments/production.rb 包含config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present?,因此您可以为您的环境进行不同的设置,而无需更改签入 SCM 的代码。
  • 启用它:"export RAILS_SERVE_STATIC_FILES=" 然后你运行 "rails s -e production" 禁用它:"unset RAILS_SERVE_STATIC_FILES"
【解决方案6】:

用于编译文件的默认匹配器包括 app/assets 文件夹中的 application.js、application.css 和所有非 JS/CSS 文件(这将自动包括所有图像资产):

如果您有其他清单或单独的样式表和 JavaScript 文件要包含,您可以将它们添加到 config/initializers/assets.rb 中的预编译数组中:

Rails.application.config.assets.precompile += ['admin.js', 'admin.css', 'swfObject.js']

http://guides.rubyonrails.org/asset_pipeline.html#precompiling-assets

【讨论】:

    【解决方案7】:

    我正在运行 Ubuntu Server 14.04Ruby 2.2.1Rails 4.2.4 我已关注部署 turorial from DigitalOcean 和一切顺利,但是当我进入浏览器并输入我的 VPS 的 IP 地址时,我的应用程序已加载但没有样式和 javascript。

    该应用使用 UnicornNginx 运行。为了解决这个问题,我使用 SSH 和我的用户 'deployer' 进入我的服务器,然后转到我的应用路径 '/home/deployer/ apps/blog' 并运行以下命令:

    RAILS_ENV=production bin/rake assets:precompile
    

    然后我只需重新启动 VPS 就可以了! 它对我有用!

    希望它对其他人有用!

    【讨论】:

      【解决方案8】:

      更改您的 Production.rb 文件行

      config.assets.compile = false
      

      进入

      config.assets.compile = true
      

      还有添加

      config.assets.precompile =  ['*.js', '*.css', '*.css.erb']
      

      【讨论】:

      • 为什么要编译?我们不假设在运行时在生产环境中编译
      • 永远不要这样做!任何在生产环境中将 config.assets.compile 设置为 true 的人都应该被枪决。
      【解决方案9】:

      如果设置了预编译,则不需要

      config.assets.compile = true
      

      因为这是为了实时提供资产。

      我们的问题是我们只在config/secrets.yml 中设置了开发密钥库

      development:
          secret_key_base: '83d141eeb181032f4070ae7b1b27d9ff'
      

      生产环境需要入口

      【讨论】:

      • 如其他答案中所述,您需要config.assets.precompile = ['*.js', '*.css', '*.css.erb'] 并运行RAILS_ENV=production bundle exec rake assets:precompile
      • 这可以在生产时编译资产,非常慢,不对
      【解决方案10】:

      首先检查您的资产,可能在预编译资产时出现一些错误。

      要在生产环境中预编译资产,请运行以下命令:

      RAILS_ENV=production rake assets:precompile
      

      如果显示错误,请先删除,

      如果出现“未定义变量”错误,请先加载该变量文件,然后再将其用于另一个文件。

      示例:

      @import "variables";
      @import "style";
      

      在application.rb文件中设置资产预编译顺序

      示例:

      config.assets.precompile += [ 'application.js', 'admin.js', 'admin/events.js', 'admin/gallery.js', 'frontendgallery.js']
      
      config.assets.precompile += [ 'application.css', 'admin.css','admin/events.css', 'admin/gallery.css', 'frontendgallery.css']
      

      【讨论】:

        【解决方案11】:

        找到这个:

        配置选项config.serve_static_assets 已重命名为config.serve_static_files 以明确其作用。

        config/environments/production.rb:

        # Disable serving static files from the `/public` folder by default since
        # Apache or NGINX already handles this.
        config.serve_static_files = ENV['RAILS_SERVE_STATIC_FILES'].present?
        

        所以设置 env RAILS_SERVE_STATIC_FILES 或使用 Nginx 来提供静态文件。 添加 config.serve_static_assets = true 仍然可以使用,但以后会删除。

        【讨论】:

          【解决方案12】:

          要在生产环境中为资产服务,您必须完成 2 件事:

          1. 预编译资产。
          2. 将服务器上的资产提供给浏览器。

          1) 为了预编译资产,您有多种选择。

          • 您可以在本地计算机上运行 rake assets:precompile,将其提交到源代码控制 (git),然后运行部署程序,例如 capistrano。这不是向 SCM 提交预编译资产的好方法。

          • 您可以编写一个 rake 任务,在每次将 Rails 应用部署到生产环境时在目标服务器上运行 RAILS_ENV=production rake assets:precompile,然后重新启动服务器。

          capistrano 任务中的代码类似于以下内容:

          on roles(:app) do
            if DEPLOY_ENV == 'production'
              execute("cd #{DEPLOY_TO_DIR}/current && RAILS_ENV=production rvm #{ruby_string} do rake assets:precompile")
            end
          end
          

          2) 现在,您拥有生产服务器上的资产,您需要将它们提供给浏览器。

          同样,您有多种选择。

          • config/environments/production.rb

            中开启 Rails 静态文件服务
            config.serve_static_assets = true # old
            
            or
            
            config.serve_static_files = true # new
            

            使用 Rails 提供静态文件会降低 Rails 应用程序的性能。

          • 配置 nginx(或 Apache)以提供静态文件。

            例如,我配置为与 Puma 一起使用的 nginx 如下所示:

            location ~ ^/(assets|images|fonts)/(.*)$ {
                alias /var/www/foster_care/current/public/$1/$2;
                gzip on;
                expires max;
                add_header Cache-Control public;
            }
            

          【讨论】:

            【解决方案13】:

            对于 Rails 5,您应该启用以下配置代码:

            config.public_file_server.enabled = true

            默认情况下,Rails 5 附带以下配置:

            config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present?

            因此,您需要将环境变量RAILS_SERVE_STATIC_FILES 设置为true。

            【讨论】:

            • 对于 Rails 5,我应该添加,我在 nginx.conf 文件的应用程序的位置块中设置了passenger_env_var RAILS_SERVE_STATIC_FILES true;
            【解决方案14】:

            我可能错了,但是那些建议改变的人

            config.assets.compile = true

            这一行的注释是:#Do not fallback to assets pipeline if a precompiled assets is missing.

            这表明,通过将此设置为 true,您并没有解决问题,而是绕过它并每次运行管道。这肯定会扼杀你的表现并破坏管道的目的吗?

            我遇到了同样的错误,这是由于应用程序在 rails 不知道的子文件夹中运行。

            所以我的 css 文件在 home/subfolder/app/public/.... 但 rails 正在寻找 home/app/public/...

            尝试将您的应用移出子文件夹或告诉 rails 它位于子文件夹中。

            【讨论】:

              【解决方案15】:

              不建议让 capistrano 进行资产预编译,因为它可能需要很长时间并且经常超时。尝试做本地资产预编译。

              1st,在 config/application.rb 中设置 config.assets.initialize_on_precompile = false 然后做本地 RAILS_ENV=production bin/rake assets:precompile 并将这些公共/资产添加到 git。

              和config/environments/development.rb,改变你的资产路径以避免使用预编译资产:

              config.assets.prefix = '/dev-assets'

              如果您有 db 连接问题,则意味着您有使用 db 的初始化程序。一种解决方法是通过将 production.rb 复制为 production2.rb 来设置新环境,并在 database.yml 中添加 production2 环境和 development 数据库设置。然后做

              RAILS_ENV=production2 bin/rake assets:precompile

              如果您仍然面临资产问题,例如 ckeditor, 将js文件添加到config/initializers/assets.rb

              Rails.application.config.assets.precompile += %w( ckeditor.js )

              【讨论】:

                【解决方案16】:
                location ~ ^/assets/ {
                  expires 1y;
                  add_header Cache-Control public;
                  add_header ETag "";
                }
                

                这解决了我在生产中的问题。将其放入 nginx 配置中。

                【讨论】:

                  【解决方案17】:

                  即使我们遇到了同样的问题,RAILS_ENV=production bundle exec rake assets:precompile 成功但事情没有按预期工作。
                  我们发现独角兽是这里的罪魁祸首。

                  与您的情况相同,即使我们曾经在编译资产后重新启动独角兽。注意到当独角兽重启时,只有它的工作进程被重启,而主进程没有被重启。
                  这是未提供正确资产的主要原因。

                  后来,在编译完资产后,我们停止并启动了 unicorn,这样 unicorn 主进程也重新启动,并提供了正确的资产。
                  与重启独角兽相比,停止和启动独角兽会带来大约 10 秒的停机时间。当长期解决方案从独角兽转移到 puma 时,这是可以使用的解决方法。

                  【讨论】:

                    【解决方案18】:

                    你不应该做的事情:

                    上面的一些同事建议你这样做:

                    config.serve_static_assets = true  ## DON”T DO THIS!! 
                    config.public_file_server.enabled = true ## DON”T DO THIS!!
                    

                    rails 资产管道说明了上述方法:

                    此模式使用更多内存,性能比默认模式更差,不推荐使用。见这里:(http://edgeguides.rubyonrails.org/asset_pipeline.html#live-compilation)

                    你应该做什么:

                    预编译您的资产。

                    RAILS_ENV=production rake assets:precompile

                    您可能可以通过 rake 任务来做到这一点。

                    【讨论】:

                    • 为什么要将构建工件添加到 git 中?您可以在构建过程中添加 rake 任务并避免大量 gitspam(特别是如果您有 uglifier 和 gzipping,您应该这样做)
                    • @Dr.Strangelove 谢谢你的评论 - 我对此了解不够 - :你能详细说明/编辑原始帖子吗?
                    猜你喜欢
                    • 2014-09-12
                    • 1970-01-01
                    • 2017-02-06
                    • 1970-01-01
                    • 1970-01-01
                    • 2013-03-14
                    • 1970-01-01
                    • 2018-12-07
                    相关资源
                    最近更新 更多