sass-rails asset pipeline: generating image paths

2019-02-08 03:48发布

问题:

In section 2.2.2, "CSS and Sass", I'm told to put image-url('delete.png') in my sass. And so I have.

However, it is generating CSS like

background-image: url(/images/delete.png)

instead of the thing that I'm told everywhere it should be generating, the correct and obvious thing,

background-image: url(/assets/delete.png)

What. The heck.

I have spent literal days trying to figure out where this is coming from.

Here's a gist of relevant settings that are resulting in this behavior. Here's a gist of the same files in an earlier version of our code base (right after we implemented the asset pipeline and it actually worked for about a week before this frustrating behavior popped up). Can you spot the differences? Any other files you can think of that might be causing this?

Note

  • We're purposely using an older version of sass-rails because a newer version was causing Stack level too deep! errors when precompiling.
  • We're using Compass.

Two hackish attempts at workarounds

Because actually troubleshooting the asset pipeline kinda sucks.

1: Put images in /images

I attempted to just move all of the images to public/images and add that as a load path. This worked in dev (images are accessible at either /assets or /images), but precompiling for production puts the fingerprinted images in /assets only (obvs), so when sass-rails puts in url(/imagse/delete-120398471029384102364.png), it can't be found.

2: Make /public/images a symlink to /public/assets

This would probably work in production, but in development the /assets folder doesn't exist, so the url(/images/delete.png) directives result in unfound images.

回答1:

If you do not have this already, name your css file *.css.scss (as opposed to .sass - if you do this, you might need to adjust the syntax of some statements). Then use the image_path helper instead of image-path, e.g.:

background-image:url(image_path('delete.png'));

I expect this to solve your issue. If it does not, what is the asset path generated by this approach for you?



回答2:

This looks to be due to your version of sass-rails (3.1.0). I can reproduce your problem (thanks for posting the Gemfile) and it goes away when bumping to sass-rails 3.1.4.

Try upgrading to 3.1.4 and clearing tmp/cache. Also make sure you're not hitting any browser caches.

I know you said 3.1.4 was causing other problems... have you tried higher versions?



回答3:

It really looks like this issue: https://github.com/rails/sass-rails/issues/57 If so you should try to find the good combination of versions between Compass and Sass-rails.

And maybe upgrade everything (Rails included) to latest versions, it's still the best way to do (use bundle outdated command in bundler 1.2 to know what Gems to upgrade)



回答4:

This is our combo of haml-rails, compass and sass-rails. We're running rails 3.2.6 though. This has worked well for us.

gem 'compass', git: 'git://github.com/chriseppstein/compass.git', ref: '3a4c5c75dca9f07f6edf2f0898a4626269e0ed62'

gem 'haml-rails', git: 'git://github.com/indirect/haml-rails.git', ref: '92c41db61f20a9f122de25bc73e5045cfccdbcd5'

gem 'sass-rails', '~> 3.2.5'



回答5:

Not necessarily a solution, but certainly an available option: If you're open to using compass spriting, you'll cut down on the number of http requests and be able to manually specify your image path with a sprite map, ie '$sprites: sprite-map("PATH/*.png");'



回答6:

Sanity check the file in your current asset pipepline. Check that it's in one of the directories listed in here:

<%= debug Rails.application.config.assets.paths %>

Next check at what relative path compass expects to find the image ( and see if it mat. According to the Compass config docs, one of these should tell you:

<%= debug config.compass.http_images_path %>
<%= debug config.compass.http_generated_images_path %>

I'm guessing it's the first one. Either way, compare their path to your image's asset_path:

<%= debug asset_path 'delete.png' %>

If the paths don't match, maybe you need to adjust the path in your environment configs (development.rb, ...) to this for example:

config.compass.http_images_path = '/assets.

Alternatively, you could move the image to where http_images_path or the http_generated_images_path expect to find it.

At the point, asset_path/asset_url (which are much less brittle than hardcoding) should hopefully work. I based this off of a similar technique I saw for stylesheets,



回答7:

For me,

Changing image_path to image-path worked for .scss. Later on, I changed to image_path again and it's working fine now.

Deleting cache didnt help me.



回答8:

After I edited my .scss file (added a space) and reload the page I got right result. After I removed the space it worked correctly.