一些资产没有加载到旧的 Rails 3-2-stable 应用程序中
Posted
技术标签:
【中文标题】一些资产没有加载到旧的 Rails 3-2-stable 应用程序中【英文标题】:Some assets not loading in an old Rails 3-2-stable app 【发布时间】:2019-04-03 00:52:27 【问题描述】:本文底部的重大更新
我有一个 Rails 3-2-stable 应用程序,我要迁移到新服务器,以便将其升级到 Rails 5。目前,它托管在 Heroku 上,并且大部分资产都显示得很好(应用程序 Just Works (TM))。我有一些随机资产在 Digital Ocean 液滴上预编译后不会显示。我正在使用 Capistrano 进行部署。
不会显示的资产的错误如下所示:
Loading failed for the <script> with source “http://stage.fancy-new-droplet.com/assets/application/application.js”.
在某些情况下,会有一个与资产相关联的哈希,如下所示:
Loading failed for the <script> with source “http://stage.fancy-new-droplet.com/assets/application/certifications-56046476595984b00d1267a4f02822e5.js
在前一种情况下,资产实际上位于public/assets/
中,而不是液滴上的public/assets/application/
。将丢失的资产移动或符号链接到该位置似乎不会影响任何事情。在后一种情况下,据我所知,这些资产并不存在于水滴上的任何地方。
对于文件名中没有散列的情况,从这里更改我的包含标签:
<%= javascript_include_tag "application/application" %>
这样的:
<%= javascript_include_tag "application" %>
会解决这个问题,但我觉得这是一个红鲱鱼考虑到预编译后似乎不存在的其他资产。
我确实遇到了一个深奥的问题,即 droplet 内存不足,并且在资产编译的中途静默失败,但我增加了可用内存,它现在甚至没有使用一半的内存。不过,它确实将 CPU 最大化 100%。我可能会尝试增加 droplet 上的 CPU 和内存。
这里是来自config/environments/production.rb
的相关资产编译行:
config.serve_static_assets = false
config.assets.compress = true
config.assets.compile = true
config.assets.digest = true
以及来自application.rb
的相关资产编译行:
config.assets.enabled = true
config.assets.version = '1.0'
在本地,一切都 100% 运行良好,没有错误。资产加载良好,我们都很好。这是我的development.rb
文件中的资产管道位:
config.assets.compile = true
config.assets.compress = false
config.assets.debug = true
我已经在生产服务器(在生产环境中)上运行了rake assets:clean
、rake assets:precompile
和rake assets:precompile:all
的各种组合,我什至已经删除了 public/assets/ 文件夹以重新开始它.一切都无济于事。
什么可能导致这些资产无法在我们的 droplet 上创建,而它们确实可以在 Heroku 上创建?
编辑
根据要求,我的 DO 堆栈只是一个 droplet(2vcpu,2gb 内存),我使用的是 Puma 和 nginx。这是我的 Capfile:
# Load DSL and Setup Up Stages
require 'capistrano/setup'
require 'capistrano/deploy'
require 'capistrano/scm/git'
install_plugin Capistrano::SCM::Git
require 'capistrano/rails'
require 'capistrano/bundler'
require 'capistrano/rvm'
require 'capistrano/puma'
install_plugin Capistrano::Puma
# Loads custom tasks from `lib/capistrano/tasks' if you have any defined.
Dir.glob('lib/capistrano/tasks/*.rake').each |r| import r
进一步编辑
我已经在application.rb
中对config.assets.initialize_on_precompile
进行了几次攻击,并在本地运行rake assets:clean, assets:precompile
和assets:precompile:all
与RAILS_ENV=production
的各种排列,但无济于事。
又一次编辑
此时我注意到,预编译生产资产似乎没有编译四个 javascript 文件和大约七个 css 文件。它似乎也没有将 application.js 放入 public/assets/application/application.js
(应用程序正在寻找的位置),而是放在 public/assets/application.js
中。
更多编辑
我已通过修复 application.js
中的 require_tree
语句解决了 JavaScript 资产无法加载的问题,现在唯一的问题似乎是缺少几个 CSS 文件。
在这个应用程序中有两个包含 css 文件的目录:
app/assets/stylesheets/
app/assets/stylesheets/application
在将近 100 个样式表中,总共有 21 个样式表无法加载。使用散列文件名 (somefile-hash.css
) 调用未加载的样式表,但这些散列文件在 droplet 上的 public/assets/
中不存在。
这是来自application.css.scss
的要求:
/*
*= require_self
*= require chosen
*= require jquery-ui/autocomplete
*= require jquery-ui/datepicker
*= require feature-carousel
*= require_tree .
*/
出于沮丧,我将= require_directory ./assets
添加到该列表中,现在我只有大约 15 个样式表无法编译/加载。这种行为对我来说没有任何意义,因为我认为 = require_tree .
会覆盖不稳定的子目录。
单独指定文件= require foo
或= require foo.css.scss
似乎也没有任何影响。
我也因为沮丧而撞了config.assets.version
,但无济于事。
此外,再多的粗话也无法说服这些资产进行编译。
【问题讨论】:
* 查看 Heroku 上Activity
选项卡下的日志,了解 Heroku 上正在运行哪些命令。 * 你确定你在 droplet 上以生产模式运行你的代码吗?你是如何验证这一点的?做因设置而异。 * 当您运行 rake assets:precompile 时,您是否在 public/assets 目录中看到带有指纹的已编译文件? * Heroku 系统设置是否使用 CDN?
另外请注意,旧版本的 Rails 会生成资产的指纹版本和非指纹版本。有时人们会错误地创建指向非指纹版本的链接。新版本的 rails 应该只生成指纹版本,所以查看你的 html 并确保所有资产链接都被指纹。
我在生产模式下运行。 RAILS_ENV
设置为生产,日志记录转到 log/production.rb
。我现在正在 Heroku 上运行相同的命令。当我运行rake assets:precompile
时,我没有看到public/assets
中的所有编译文件,我只看到其中一些,这是我的问题的问题。 Heroku 没有设置为运行 CDN。在丢失的资产中,我既没有指纹也没有非指纹副本,显然是编译后的。
【参考方案1】:
也许尝试在 production.rb 中更改这些但不能保证,可能值得一试。
config.serve_static_files = true
config.assets.compile = false
此外,如果您在 Gemfile 中有此内容,您可能想尝试在部署之前将其注释掉并在本地捆绑安装。
gem 'rails_12factor', group: :production
Heroku 需要那个?,但你在 DO 上可能不需要它。见https://github.com/heroku/rails_12factor
另外,如果您可以发布有关您的 DO 堆栈以及您的 Capfile 的更多相关信息,请提供
【讨论】:
我的 Gemfile 中的任何地方都没有rails_12factor
。对我的 production.rb 文件进行建议的更改会为第一个 CSS 资产抛出 500 ActionView::Template::Errror
,说明它没有预编译。【参考方案2】:
只需在您的 production.rb
上更改此设置即可:
config.serve_static_assets = true
【讨论】:
这并没有改变我的任何行为。【参考方案3】:默认情况下,资产管道会连接您的资产以仅生成和提供指定文件“application.js”、“application.css”和图像/字体。
如果您通过 javascript_include_tag
或 stylesheet_link_tag
帮助程序在应用程序中明确包含其他 css/js 文件,则需要通过 application.rb
中的 config.assets.precompile +=
设置手动将这些文件添加到管道中或初始化程序。
目前,这些文件应该已经通过require_tree .
指令包含在您的application
清单中。因此,这些样式可能现在也正在应用中。如果是这种情况,您只需删除单独添加各个样式表的代码即可摆脱 404。
仍然不确定应用在 heroku 上的运行情况如何,也许您有一些 heroku 配置可以提供静态资产服务。
【讨论】:
就是这样!非常感谢!我必须单独添加每个文件,但它可以工作。我不能给它*.css
,因为项目中包含一个古老版本的引导 gem 中的错误,但我会接受它。再次感谢!堆栈溢出解锁后,我将立即奖励赏金。谢谢!以上是关于一些资产没有加载到旧的 Rails 3-2-stable 应用程序中的主要内容,如果未能解决你的问题,请参考以下文章
[Dead]如何使用异步回发成功 POST 到旧的 ASP.NET 站点