How I Organized My Javascript Assets in Rails

Lately, I have been introducing javascript and coffeescript in (with structural architecture issues as a side effect, but that’s another story …).

Here are the general goals I had when using the rails asset pipeline :

  • most of js compiled in a single file
  • no js code in your html files : I want to use unintrusive javascript techniques, and have some outside js hook code that will wire js and html together
  • sometimes, I want some js code to be only explicitly included by some particular pages (example: hooking a timer on the document ready event of a particular html page). This means that I cannot simply compile all js code in a single minified file
  • In unit tests, I want to be able to manually set up and tear down the js hooks

So, here is how I eventually organized my js code :

  • I create a specific dependencies.js file that will require all outside dependencies
  • I split my js code under 3 subdirectories :
    • explicit : hooks that will be explicitly included
    • hooks : all the other hooks
    • application : all the real code
  • In my application.js, I include dependencies and all files under application and hooks. Here is my app/assets/javascript/application.js
//= require dependencies.js
//= require_tree ./application
//= require_tree ./hooks
  • In my tests, I only load dependencies and files from the application directory. Here is my spec/javascript/
#= require ../../app/assets/javascripts/dependencies.js
#= require_tree ../../app/assets/javascripts/application
#= require_tree ./
  • Hook code only consists of calling a setup function from the ‘real’ code. For example, here is my app/assets/javascript/hooks/cart_lines/ file

this setUp function is defined in the app/assets/javascript/application/cart_lines/ file

  • This way, from the unit tests, I can explicitly call this setUp function, here is the beginning of my spec/javascript/application/cart_lines/ file
describe 'mesCourses.cartLines.index', ->

  beforeEach ->


And you, how are you organizing your javacript assets ?