我正在更新Rails 3应用程序以使用Rails 3.1,作为其中一部分,我正在利用新的 Assets 管道。到目前为止,除了我无法解决的一个相当烦人的问题之外,我已经将所有工作都进行了。
该应用程序及其所有 Assets 在开发中都可以正常工作,但是在生产中,可以使用Passenger(http://the-host/sub-uri/
)将其部署到子URI。问题在于, Assets 在部署过程中被预编译,而我的CSS文件之一(这是一个.css.scss
文件)正在使用image-url
gem中的sass-rails
帮助程序。由于在预编译过程中,路径被硬编码到预编译的CSS文件中,因此sub-uri没有考虑:
在我的.css.scss
文件中:
body { background-image: image-url("bg.png"); }
编译后的
application-<md5-hash-here>.css
文件中的结果:body { background-image: url(/assets/bg.png); }
要使其正常工作应该是什么:
body { background-image: url(/sub-uri/assets/bg.png); }
这种情况是否要求太多?如果是这样,我将不得不切换回旧的非 Assets 流水线方式,只从
public
提供我的图像和CSS。但是,似乎有些事情应该被考虑和解决……?我错过了解决方案吗?编辑1:我应该注意,使用erb solution会产生与预期相同的结果。
编辑2:响应Benoit Garret的评论
不,问题与
config.assets.prefix
无关。我尝试设置(设置为/sub-uri/assets
而不是默认的/assets
),但事实证明这是错误的做法-似乎此设置已与Rails应用而非服务器根目录相关。删除该错误(并因此恢复为默认值)已修复了所有引起的奇怪问题(并且很多 Assets 最终都以/sub-uri/sub-uri/assets
结尾-这都是非常奇怪的)。唯一的问题是image-url
帮助器和 friend 在预编译时不会选择子URI。不用说,这是合乎逻辑的,因为当对其进行预编译时,它可能无法知道当它在Passenger下运行时,将以这种方式进行配置。我的问题是如何告知这一点,从而最终获得预编译结果中的正确路径。如果确实可以做到。我当前的解决方法是像这样在CSS中引用iamge:
url(../images/bg.png)
并将其放置在非流水线的public/images
位置。由于它无法从指纹识别和管道提供的所有内容中受益,因此非常不理想。 最佳答案
最终,我制定了一些解决方法/解决方案。
1)从https://github.com/rails/sass-rails/issues/17看来,这可以在sass-rails中修复。我已经按照上面链接中建议的补丁进行了猴子补丁helpers.rb的工作。我只需在deploy.rb
的 Assets 预编译行中设置所需的环境变量即可。
我将所有猴子修补程序都放在一个文件config/initializers/gem_patches.rb
中。在此文件中,我将此方法修补为:
module Sass
module Rails
module Helpers
protected
def public_path(asset, kind)
path = options[:custom][:resolver].public_path(asset, kind.pluralize)
path = ENV['PRODUCTION_URI'] + path if ENV['PRODUCTION_URI']
path
end
end
end
end
2)或者,如果您可以在CSS中嵌入图像,则可以将样式表更改为.erb扩展名,并用
image-url("bg.png")
替换url(<%= asset_data_uri "bg.png" %>)
,而无需更改sass-rails。 asset-data-uri
不作为纯Sass函数存在,因此您必须使用Rails帮助程序asset_data_uri
。关于ruby-on-rails-3.1 - 部署到子URI时,Rails 3.1中的预编译 Assets 损坏,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/7293918/