I'm starting a new project in Rails, and it looks like the application.js manifest file is doing something funny with the javascripts that I reference - does it cache those files as part of the asset pipeline?
Here's what happened. I added a javascript file named jquery.autoresize.js to the vendor/assets/javascripts folder, and then referenced the file in the application.js manifest like this:
//= require jquery.autoresize.js
Then I started up the rails server. But after navigating around in my app, I realized that I had accidentally added the wrong version of the jquery.autoresize.js file. So, I deleted that file and then added the correct version to the vendor/assets/javascripts folder. But, to my horror, when I reloaded the page, it is still loading the old javascript file.
I tried emptying my browser cache, then exiting and restarting the Rails server, but to no avail. I hacked a solution together by simply renaming my javascript file and referencing the new name, which worked fine. But there has got to be a better solution to this.
Does the new asset pipeline cache the files you reference somehow? If so, how can I clear that cache? Thanks for any help!
I'm assuming we're talking about the production environment.
When you change any of your javascripts or stylesheets in the production environment, you need to run rake assets:precompile
; this task compiles and compresses the various .js and .css files and creates the application.js and application.css files that is loaded by your views.
It's possible that if you replaced jquery.autoresize.js
with a version with an older timestamp, the precompile step might skip it, thinking the compiled version is up-to-date. You can avoid that by running rake assets:clean
first, forcing it to rebuild everything in the public/assets
directory from scratch.
Also try rake assets:clobber
. This will totally reset everything and delete all compiled assets. In addition, I often need to set the environment before pushing to production by going: RAILS_ENV=production rake assets:precompile
.
Rails automatically clears the cache for an individual file every time that the contents are edited. To clear the cache for a single file, simply open the file, edit a line of code, and re-save it. Rails will clear the cache for that file, and the browser will load the new file the next time the page is loaded.
The reason jquery.autoresize.js was using the old cached version of the file was because the old version was deleted and then the new version was copied and pasted with the same name into the same folder. Because the file itself was never edited, Rails continued to use the old file that was cached.
This is because the asset pipeline uses fingerprinting for the cache.
Fingerprinting is a technique that makes the name of a file dependent on the contents of the file. When the file contents change, the filename is also changed. For content that is static or infrequently changed, this provides an easy way to tell whether two versions of a file are identical, even across different servers or deployment dates.
When a filename is unique and based on its content, HTTP headers can be set to encourage caches everywhere (whether at CDNs, at ISPs, in networking equipment, or in web browsers) to keep their own copy of the content. When the content is updated, the fingerprint will change. This will cause the remote clients to request a new copy of the content. This is generally known as cache busting.
The technique that Rails uses for fingerprinting is to insert a hash of the content into the name, usually at the end. For example a CSS file global.css could be renamed with an MD5 digest of its contents:
global-908e25f4bf641868d8683022a5b62f54.css
So, if you delete a file you're referencing in the manifest, and then copy in a new file with the same name, the cache busting never occurs. When you edit the file, the fingerprinting kicks in, and a new hash is generated for the file name. This busts the cache for that file.
For the full story, see What is Fingerprinting and Why Should I Care?.
rake assets:precompile
to put the files in the public/assets
directory; that should be the solution unless you've changed the default config - benzado 2012-09-05 23:15
rake assets:clean
, then rake assets:precompile
, as well as copying the new file over again and restarting the server. Nothing worked until I opened the new file, added a few dummy words at the end, then deleted them and saved the file. Rails is becoming too complex for it's own good - you know that's the case when simple things require complex steps to get done - abbottjam 2014-02-13 14:33
rake assets:clean
rake tmp:clear
rake tmp:cache:clear
rake cache:clear
Darwayne 2015-01-16 14:45
touch
on the file to update the timestamp on it. You can see if this is the issue by running ls -l
and checking the modification date - Ian 2015-06-16 21:56
application.css
include a single file (with sprockets' *= require
syntax) which then includes further files using compass's @import
. Changing files below the @import
used to fix things but then after a precompile in dev once it started returning the cached precompiled version. I fixed this by modifying application.css
and rerequesting. That busted the cache and now it reloads appropriately - jwadsack 2015-07-03 22:50
rake tmp:clear
did nothing, I really had to add an empty line to the file to make it work - Jonathan Allard 2016-07-04 21:27
rake tmp:clear
did the trick for me, I'm using less-rails.
rails assets:clean
does not work for this - Ryan 2016-12-03 20:05
I use config.assets.version = '1.01019'
in my application.rb
to bust the entire cache. When I want to push a complete new version, I increment the version and that does the trick. This takes care of those edge cases where Rails does not recompile as asset for whatever reason.