Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Asset Pipeline Cacheing CSS?

I am working on a Rails 3.1 app. I have created an application.css.scss.erb file. The .erb is in the end because I want to load a variable from the config file as the color variable in the css:

$highlight1: #<%= COLOR.highlight1 %>;
$highlight2: #<%= COLOR.highlight2 %>;

Everything works fine, but the problem I am having is that whenever I change a value inside COLOR.highlight1, it doesn't reflect the change until I go in to my css file and change something (i usually add some spaces and save it). Thats when I see the change. Clearly rails is looking to see if the file was changed in order to update the change.

Is there any way that at least during development, this can be turned off and I can see the changes without having to also modify the css file?

Any critique/opinions on my technique are also welcome

like image 236
alik Avatar asked Oct 05 '11 02:10

alik


People also ask

How do you Precompile an asset?

To compile your assets locally, run the assets:precompile task locally on your app. Make sure to use the production environment so that the production version of your assets are generated. A public/assets directory will be created. Inside this directory you'll find a manifest.

What does rake assets Clean do?

rake assets:clean Only removes old assets (keeps the most recent 3 copies) from public/assets . Useful when doing rolling deploys that may still be serving old assets while the new ones are being compiled.

How does rails asset pipeline work?

The asset pipeline provides a framework to concatenate and minify or compress JavaScript and CSS assets. It also adds the ability to write these assets in other languages such as CoffeeScript, Sass and ERB. Prior to Rails 3.1 these features were added through third-party Ruby libraries such as Jammit and Sprockets.


2 Answers

The Sprockets depend_on directive is used to declare these kinds of dependencies. So at the top of your css.scss.erb file, with the other directives (require and friends), put something like:

//= depend_on "/path/to/colors.rb"

Then when the file /path/to/colors.rb changes, it will force the css to update too.

Unfortunately, I have never gotten this to work with a relative path to a file outside of one of the asset directories (javascripts/stylesheets/images) so there may be something in the way Sprockets resolves paths that prevents this, or else I'm missing something. That leaves you with the options of specifying an absolute path, which will almost certainly not work in across all your app environments, or putting the constants file into your asset directories (app/assets/stylesheets/colors.rb, for example).

For reference, here's the doc for the depend_on directive from the Sprockets (2.0.3) source, in sprockets/directive_processor.rb

  # Allows you to state a dependency on a file without
  # including it.
  #
  # This is used for caching purposes. Any changes made to
  # the dependency file will invalidate the cache of the
  # source file.
  #
  # This is useful if you are using ERB and File.read to pull
  # in contents from another file.
  #
  #     //= depend_on "foo.png"
  #

If anyone does know a way to specify relative paths to other places like config/initializers or something, please let me know!

like image 89
David Faber Avatar answered Nov 12 '22 15:11

David Faber


In addition to David Faber's answer. I needed to use relative paths too.

I wanted to generate a js file with the locale dictionary, which would update if the locale files were changed:

//= depend_on "../../../config/locales/en.yml"
//= depend_on "../../../config/locales/ja.yml"

var locales = <%= locales.to_json %>;

Turns out that currently (Rails 3.2.3) relative paths only work if the relative path is also in the assets path!

So the ugly solution is to add the path in config/application.rb:

config.assets.paths.unshift Rails.root.join("config", "locales").to_s
like image 20
Gavin Brock Avatar answered Nov 12 '22 14:11

Gavin Brock