55

I prefer not to concatenate JavaScript files in development mode, but serve them as individual files. So I configured:

development.rb:

config.assets.compress = false
config.assets.debug = true
config.assets.compile = true

In my /app/assets/javascript directory I have:

  • reviews.js
  • reviews/
    • foo.js
    • bar.js

reviews.js:

//= require jquery
//= require jquery_ujs
//= require_tree ./reviews

I include the JavaScript using <%= javascript_include_tag "reviews" %> in my layout. The generated page correctly references the three scripts individually and reviews.js is essentially empty. So far so good.

Now when I precompile my assets for production using rake assets:precompile the three JavaScript files are concatenated into reviews.js. This is all fine for production but now, in development mode, the concatenated reviews.js is served in addition to the two individual files.

Of course, this leads to all kinds of nasty bugs when developing because now, the content of foo.js and bar.js is served twice, one of them in a potentially older version in reviews.js.

How can I make sure Rails doesn't use the precompiled assets in development mode?

gariepy
  • 3,576
  • 6
  • 21
  • 34
Ortwin Gentz
  • 52,648
  • 24
  • 135
  • 213

4 Answers4

83

In config/environments/development.rb set:

config.assets.prefix = "/assets_dev"

so that in development mode Rails will look there (but it will not find anything, as you will not compile assets in development (this is indeed what you are trying to do -- not compile assets)).

When precompiling for production, use

RAILS_ENV=production rake assets:precompile

so it compiles into the default assets folder, public/assets.

user664833
  • 18,397
  • 19
  • 91
  • 140
Haim Lankry
  • 879
  • 7
  • 4
  • 15
    This should be the selected answer. Good find. – Tyler Collier Aug 03 '12 at 23:48
  • 1
    It should be noted that this change will alter the "assets/" path that Rails uses in its URLs, so that you get images like `http://127.0.0.1:3000/assets_dev/favicon.ico` – Tom Corelis Oct 02 '12 at 06:15
  • Sometimes you have to precompile assets. So this is the best answer. Otherwise you would need to keep deleting and regenerating assets. – John Hinnegan May 04 '13 at 21:25
  • This just bit me in the test environment: Selenium was using precompiled assets and my Ajax tests were failing. I'm going to try this workaround in `config\environments\test.rb`. – Mark Berry Sep 30 '13 at 19:46
  • Looks like this no longer works as of Rails 4. It seems to use `config.assets.prefix` for both the directory to precompile files to and the directory to pull assets from. – Undistraction Jan 23 '14 at 12:19
  • In Rails 5.1.6 this won't work if there's `public/assets/` dir present. Server will search for `assets/assets_dev/` and because it will not find a thing the browser will log 404s. If you want to trick the server into serving uncompiled assets, you can rename the `public/assets/` to eg. `public/assets2` or anything. Afaik, the `assets/` dir isn't configurable. Don't forget to restart the server after the rename. – medik Jul 19 '18 at 16:22
55

It sounds like you are precompiling locally. Because the files exist in the expected location they are being served by your dev server, and the requests are not going to Sprockets.

The only way to stop this is delete the compiled files.

Normally you do not need to compile locally. It is expected that in almost all cases the precompile task will be run during deployment of the app. There is a Capistrano recipe for this on the asset pipeline guide page.

If you do need to have those files locally committed to your repo you could use a branch to avoid the problem. Reserve your master branch for production code, and make a second branch for dev. Only compile and commit assets on master. When you switch to dev, they will be gone. Merge dev into master as required.

Edit: Make sure you force your browser to update (control + F5) or you may find the old assets used from the browser cache!

Richard Hulse
  • 10,383
  • 2
  • 33
  • 37
  • Thanks for the advice, I deleted the compiled files locally and configured to have them compiled on git push to heroku. – Ortwin Gentz Nov 09 '11 at 12:08
  • 1
    That was the answer I needed. It's true I don't need these precompiled assets locallywhilst I am developing, but as I'm learning how to configure the asset pipeline, I actually DO need them to test my production mode locally, rather than wait for the surprise on Heroku! For now I'll change the directory name (or put them onto a git branch), but still it's a shame it's one more thing I need to think about, rather than a config option in development env to say "ignore the public/assets directory" which I was hoping for. – Phantomwhale Jan 20 '12 at 02:20
  • 1
    You might have to don't forget to clear your browser cache too so the browser doesn't use the application.js you accidentally loaded before you rm -rf'd public/assets – Bryan Larsen Feb 29 '12 at 15:58
  • Good point, I will edit that answer so that is clear up-front. – Richard Hulse Feb 29 '12 at 19:43
17

in config/environments/development.rb set:

config.serve_static_assets = false

and no files from /public will be served

Baylor Rae'
  • 3,995
  • 20
  • 39
Peter Madsen
  • 419
  • 5
  • 6
  • 3
    bear in mind that any uploaded files in the public folder won't be served so it's probably best to avoid this. – Adam Waite May 15 '13 at 21:07
  • 1
    In latter version this has been changed to `config.serve_static_files` – Ruby Racer Sep 22 '15 at 07:17
  • In Rails 5.1.6 this will turn off serving assets from the `public/` but it still won't turn on serving assets from `app/assets/` – simply no assets will be served. – medik Jul 19 '18 at 16:08
0

I tried this and it worked. rake assets:precompile RAILS_ENV=production

I observed that the new version of assets pipeline does this when you run rake assets:precompile does rake assets:precompile:all

Uchenna
  • 4,059
  • 6
  • 40
  • 73