Rails 4:资产未在生产中加载
Posted
技术标签:
【中文标题】Rails 4:资产未在生产中加载【英文标题】:Rails 4: assets not loading in production 【发布时间】: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
。
刚刚添加到上面。我在做<%= stylesheet_link_tag "style", media: "all", "data-turbolinks-track" => true %>
好的,所以我会推荐两件事:1. 如果此行被写为public/assets
的路径,请检查生成的源代码;以及 2. 仔细检查是否没有其他指令试图加载它css 文件(可能是硬编码的)
我不能说使用 .erb 是否有问题,因为我从不这样做:.home background: #FFF url(<%= image_path 'hippopotamus.jpg' %>) no-repeat;
实际上可以在 sprocket 中替换为 .home background: #FFF url(image-path('hippopotamus.jpg')) no-repeat;
。如果这有帮助,也许你可以试试。
您是说我可以在我的 css 文件中动态引用该引用而不添加 .erb 扩展名?我更改了它,因为我不希望在我处于开发模式时链接断开。
【参考方案1】:
Rails 4 不再生成资产的非指纹版本:不会为您生成 stylesheets/style.css。
如果您使用stylesheet_link_tag
,则会生成指向您的样式表的正确链接
另外styles.css
应该在config.assets.precompile
中,这是预编译的东西的列表
【讨论】:
我在 /public/assets/ 目录中看到了指纹文件。在我的布局中,我有这个:<%= stylesheet_link_tag "styles", media: "all", "data-turbolinks-track" => true %>
这是不正确的吗?`
由于某种原因,当我查看源代码时,生产部署仍然指向原始文件<link data-turbolinks-track="true" href="/stylesheets/bootstrap.min.css" media="all" rel="stylesheet" />
但是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.04、Ruby 2.2.1 和 Rails 4.2.4 我已关注部署 turorial from DigitalOcean 和一切顺利,但是当我进入浏览器并输入我的 VPS 的 IP 地址时,我的应用程序已加载但没有样式和 javascript。
该应用使用 Unicorn 和 Nginx 运行。为了解决这个问题,我使用 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) 为了预编译资产,您有多种选择。
您可以在本地计算机上运行 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 谢谢你的评论 - 我对此了解不够 - :你能详细说明/编辑原始帖子吗?以上是关于Rails 4:资产未在生产中加载的主要内容,如果未能解决你的问题,请参考以下文章
Rails 应用程序未在弹性 beantalk aws 上加载资产
ckeditor gem custom config.js 未在生产中加载