生产环境中的Rails 3.1资产管道

6

我正在使用资产管道(在Rails 3.1.3中),但在生产环境中遇到了一些困难。

情况

在我的/app/assets/stylesheets目录中,我有以下文件:

application.css --> this is the default rails one
stylesheet.css --> This is my custom stylesheet

我花费了很多时间将我的stylesheet.css文件包含在生产环境下的/public/assets/目录中(通过运行rake assets:precompile命令),最终成功了,我是通过将以下一行代码添加到我的application.rb文件中实现的:

    config.assets.precompile += ['stylesheet.css']

我知道在生产环境中应该使用正确的预编译stylesheet.css文件。

我的问题

我的问题是当使用stylesheet_link_tagstylesheet.css文件时。它会变成:

<%= stylesheet_link_tag "stylesheet" %>生产环境中会被解析为<link href="/stylesheets/stylesheet.css" media="screen" rel="stylesheet" type="text/css"> ,而我期望路径能够像在开发环境中那样解析为/assets/stylesheet.css即使在开发环境中,也如此。

更令人惊讶的是,application.css的表现完美无缺,即使<%= stylesheet_link_tag "application"%>被解析为<link href="/stylesheets/stylesheet.css" media="screen" rel="stylesheet" type="text/css">。但我不理解的是,rails 3.1中没有public/stylesheets/目录。

有任何想法吗?


到目前为止,我找到的唯一解决方案是使用 <%= stylesheet_link_tag "/assets/stylesheet.css" %>。虽然不太令人满意,但它能够正常工作! - rpechayr
4个回答

8

Richard Hulse的回答指引我走向了正确的方向。事实上发生的是非常微妙的事情。

我的问题的答案是Rails 3.1 assets has no fingerprint in production

基本上,我的项目使用mongoid而不是ActiveRecord。根据Mongoid 文档 关于配置,可以修改application.rb文件来不包括ActiveRecord,这意味着删除:

require railties/all

并将其替换为:

require "action_controller/railtie"
require "action_mailer/railtie"
require "active_resource/railtie"
require "rails/test_unit/railtie"
# require "sprockets/railtie" # Uncomment this line for Rails 3.1+

我之前一直使用Rails 3.0.x进行操作,以至于没有注意到与Rails 3.1相关的注释。
我的问题在于我没有要求使用sprockets!
谢谢大家的帮助!

7
在开发中,您可以访问stylesheet.css是因为Sprockets的工作原理。在开发模式下,所有对/assets下内容的请求都会发送到Sprockets进行处理。Sprockets将直接将请求映射到路径,一对一,因此您可以访问存储在app/assets/etc中的任何资源。
所有请求都通过Sprockets进行处理;它向您的浏览器提供文件。
在生产中,文件名会添加指纹,并且期望您将资产预编译为静态文件。这是出于性能原因- Sprockets无法快速服务大量请求。
只有默认清单引用的CSS和JS文件才会编译到application.css和application.js中。除非将其添加到配置文件中的config.assets.precompile数组中,否则不会预编译其他引用的文件。
你说文件的解析路径为/stylesheets/stylesheet.css。在开发中,管道应该生成这样的路径:/assets/application.css。在生产环境中,文件名中应该有一个指纹。你所发布的内容表明管道未启用(这些是旧的、3.1之前的文件位置)。
如果这是一个升级后的应用程序,很可能你已经错过了一些关键的配置选项。这是开发和生产问题的主要原因。检查管道选项是否与管道指南最后一节中的选项完全相同。(我猜你缺少了application.rb中的config.assets.enabled = true
为了清晰起见,我建议将stylesheet.css的名称更改为admin.css,同时将其包含在预编译数组中(就像你已经做过的那样)。
使用正确的配置选项,并将您的管理清单包含在预编译中,应该使前端可用application.css和后端可用admin.css,两者都可以通过助手方法链接。

你说的很有道理。然而,我在我的application.rb文件中确实有config.assets.enabled = true指令。而且这个应用程序是一个全新的Rails 3.1.3应用程序。既然你说生产环境中似乎没有启用资产管道(指纹缺失),我会尝试进一步调查我的问题。 - rpechayr
好的,我明白了!我写了另一个关于这个问题的答案。我正在使用mongoid,实际上我没有包含sprockets!这个问题让我朝着正确的方向前进:https://dev59.com/JVvUa4cB1Zd3GeqPx-Z6 - rpechayr
是的,那个问题总是会让你措手不及!;-) - Richard Hulse

1

你的 application.css 应该是一个清单文件,这意味着当你运行程序时,它应该自动包含你的 stylesheet.css

确保它有这两行。

application.css:

/*
 *= require_self
 *= require_tree . 
*/

如果是这样,那么其他某些东西可能没有正常工作,您不应该需要这行代码:

config.assets.precompile += ['stylesheet.css']

如果那个方法也不起作用,确保你已经按照这个 Asset Pipeline 指南启用了所有的设置。

我想要的是不要包括application.css文件。这就是为什么我使用另一个css文件的原因。这样做的原因是我想根据我是在前台还是后台来使用不同的css文件。 - rpechayr
那我有点困惑,你的 application.css 文件是否仍然在上面有清单?还是 stylesheet.css 有?如果有任何一个,请贴出清单。 - Azolo
application.css没有如此广泛的清单。它没有require_tree .指令。相反,它有一个require_tree ./admin,因为我只在后台使用它。 - rpechayr

0

当我在查看actionpack以查找可能导致此问题的原因时,我在3.1.1的更改日志中发现了这个小宝石:

javascript_path and stylesheet_path now refer to /assets if asset pipelining is on.

所以,如果你正在使用 3.1.0 版本,请升级到 3.1.1 版本并查看是否解决了问题。如果你已经升级了,那么我们回到了原点。但是,这似乎描述了你的问题,因为 stylesheet_link_tag 内部使用了 stylesheet_path

我更新了我的问题。这个应用程序是一个Rails 3.1.3应用程序。无论如何,谢谢你的提示。 - rpechayr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接