31

In Rails 3.1, you must whitelist files that you want included in asset precompilation. You must open up config/environments/production.rb and explicitly include assets you want precompiled:

config.assets.precompile += ['somestylesheet.css']

If you don't do this this and you run rake assets:precompile, your asset will not be copied to public/assets, and your app with raise an exception(therefore causing a 500 error in production) when an asset is not found.

Why is this necessary? Why aren't all assets automatically precompiled?

This current approach creates extra code and stress when deploying. Wouldn't it be easier to blacklist/exclude assets so things worked right out of the box? Anyone else share these feelings?

dhulihan
  • 11,053
  • 9
  • 40
  • 45
  • 1
    Just to clarify, this is more of a criticism of the need to **explicitly** specify an asset. The rails precompilation process doesn't just compile code, it also copies the compiled asset code to a public directory for your webserver. Even if an asset doesn't require compilation (like a plain `.js` file), you still need to tell your app to "precompile" it, so it gets copied to `public/assets`. If you don't do this, the page requiring the asset throws an exception. – dhulihan May 22 '12 at 20:06
  • 1
    If you're in the practice of combining and minifying files, you probably don't want to precompile all of your assets. This technique is for assets you plan to individually include. For example, in application.js, you may `//= require` many other JS files that do not need to be precompiled. – Simon Peck Apr 06 '13 at 21:51
  • @Simon Peck: You're right, some assets do not need to be precompiled, but if they're not explicitly included, they won't be copied to the final asset location (eg: `public/assets`), and won't be found when requested. Adding the asset to `application.js` using `//= require` works, but adds bandwidth overhead and isn't appropriate for assets that won't be used site-wide. – dhulihan Apr 08 '13 at 00:59

3 Answers3

21

Most assets are automatically included in asset precompilation. According to the RoR Guide on the Asset Pipeline:

The default matcher for compiling files includes application.js, application.css and all files that do not end in js or css: [ /\w+\.(?!js|css).+/, /application.(css|js)$/ ]

You would use config.assets.precompile if you have additional assets to include:

config.assets.precompile += ['admin.js', 'admin.css', 'swfObject.js']

Or you could overwrite it.

Stuart M
  • 11,458
  • 6
  • 45
  • 59
Simon Peck
  • 507
  • 3
  • 8
  • 1
    The keyword here is *most*. You still need to explicitly add those extra arbitrary assets like `admin.js` to your app configuration or some pages might raise exceptions. I'm debating that this extra step may not be necessary. – dhulihan May 22 '12 at 20:25
8

I think it has to do with the pipeline/sprockets ability to require separate files.

For example, I have an admin.js file in my app/assets/javascripts folder. But all it does is require several other .js files.

//= require jquery
//= require jquery_ujs
//= require jquery.colorpicker.js
//= require jquery.wysiwyg.js
//= require wysiwyg.image.js
//= require jquery.fileupload.js
//= require jquery.fileupload-ui.js
//= require codemirror.js
//= require css.js
//= require admin_load

This is because (a) I'm using external js plugins and (b) I like to keep things like jQuery onload handlers in separate files.

If every .js file was precompiled, then it would precompile each one of these individual files–which is totally unnecessary. All I want/need is the single admin.js file precompiled.

Same goes for CSS files.

Callmeed
  • 4,972
  • 5
  • 34
  • 49
  • 4
    True, there are some assets that don't require any sort of compilation (like plain `.js` files), and they shouldn't be compiled, like you said. However, if you're using this asset somewhere other than a sprocket manifest (eg: using `javascript_include_tag 'admin.js'` in a view), and you didn't explicitly include this arbitrary asset in your app's config, it will never get copied to `public/assets` and the page will raise an exception in production. – dhulihan May 22 '12 at 20:21
2

The assets precompile to me is cool so you dont end up deploying assets that you do not want. Dont also forget about the uglifer gem that helps compress your javascripts. Imaging all this are not existing and you just deploy your app and you find out that you have unused css files and uncompressed javascripts. how would you feel. this is just my own opinion and i say the asset pipeline is the coolest thing in rails.. Being able to manage all your assets properly.

And mind you if i am rails i would not want to compile assets that you would not want so you would say in your mind why did this guy compile these assets.. :)

Uchenna
  • 4,059
  • 6
  • 40
  • 73
  • Good point, thanks for the feedback. If an asset isn't being used in the application at all, it shouldn't be a part of its file structure. Unless the unwanted asset is part of a 3rd party gem that has other desirable non-asset functionality. – dhulihan Nov 05 '11 at 02:17
  • 4
    I would rather have unused assets than users seeing pages 500 because something was not explicitly compiled. – Gunchars Aug 08 '13 at 06:37