denishaskin
denishaskin

Reputation: 3425

Rails 4 assets - two different digests getting generated

I clearly must be Doing Something Wrong here. I'm wrestling with the asset pipeline (again). I have a custom font, and it seems to me to get everything to compile properly I need to use asset_path() in multiple places, but it's having an unexpected effect.

I realize there are several ways to do this, but here's what I have currently:

In application.css.scss.erb: @import "<%= asset_path("my-font.css") %>";

my-font.css's source file is app/assets/stylesheets/my-font.css.erb (it needs to be an .erb because I am also using asset_path() there as well).

In application.rb I am adding my-font.css to the precompile list. config.assets.precompile << 'my-font.css'

When I clean out public/assets and run rake assets:precompile Everything's getting compiled, with digests, but the digest applied to the actual file is not the same as the digest calculated and put in to application.css.

The resulting file is public/assets/my-font-2f25682a1ea904a866ef9f44101a5a2e.css but in public/assets/application-bba2edaee36771f4bdb5c89b8ec90aaf.css the reference to it is: @import url(/assets/my-font-ed843d3b174ca427edf963e473ad9e9b.css);

I realize I'm probably using asset_path() more than I should, and also importing files via url() instead of requiring them, but this has gotten me the closest to having things working.

I suspect one of the digests is being calculated on my-font.css before it goes through ERB, and the other after, but I don't understand why nor how to fix it.

Suggestions?

Upvotes: 6

Views: 1272

Answers (2)

Winfield
Winfield

Reputation: 19145

I've resolve this kind of dependency by injecting the raw contents of the asset you want to bundle into a composite asset like application.scss.erb. You need to explicitly declare the dependency (so that changes in my-fonts.css cause a regenerations of application.css) and then inject the contents:

application.scss.erb:

// Should be at Top of File
//= depend_on_asset my-fonts.css

//... wherever in the file you want the contents injected:
<%= environment['my-fonts.css'] %>

How does this work? During asset pipeline compilation, the environment here has a hash of all pre-compiled asset contents. This allows you to inject the compiled contents from my-fonts.css into your composite asset. Because we're manually injecting the value, we need to explicitly create a dependency to track this relationship via depend_on_asset.

One thing to keep in mind is that multiple asset pre-processors (SCSS, ERB, etc) are processed from the "outside in", so the contents of the my-fonts.css asset will be compiled/injected during the ERB processing as CSS output. They will be included within the asset before SCSS processing. This shouldn't pose a problem, because if this is an SCSS asset, any SCSS references will be compiled before injection into the parent asset.

Upvotes: 0

Ahmad Sherif
Ahmad Sherif

Reputation: 6213

I would guess that you're cleaning your assets just by emptying public/assets. That's not enough, you'll also need to empty your tmp/cache/assets, or just run rake assets:clobber to do both.

Upvotes: 6

Related Questions