57

As per 'unobtrusive JavaScript' recommendations I want to separate my JavaScript logic into
separate files. However I don't know how to organize them.

Should I:

  1. Just throw all application javascript into Application.js file and load it with layout page? This is simple approach but I will end up with a bloated Application.js. Some users might want to visit only a couple of pages, but this entire file would preloaded which is not good.
  2. Or should I create a separate javaScript file for each view and load them independently? This creates a set of questions. How to link each js file to corresponding view?
    Thanks.
Aamir
  • 16,329
  • 10
  • 59
  • 65
Valentin V
  • 24,971
  • 33
  • 103
  • 152

5 Answers5

117

Load the main JavaScript in application.js every time. Now create files for different needs. Create a form.js file, a myfancypart.js file etc. Don't load them in the application.html.erb layout. Load them dynamically when you need them:

application.html.erb:

<%= javascript_include_tag "application" %>
<%= yield :javascript_includes %>

top of your view.html.erb:

<% content_for :javascript_includes do %>
  <%= javascript_include_tag "forms.js" %>
<% end %>

Everything in the content_for block will be loaded at yield :javascript_includes.

Lennart Koopmann
  • 20,313
  • 4
  • 26
  • 33
  • 11
    This is fine for development, but in production you want as few HTTP requests as possible. Loading all your js up front in one request that gets cached might lead to better performance. – jonnii Mar 02 '09 at 12:47
  • 3
    rails3 fixes that issues with the asset pipeline for production. – Michael Durrant Nov 13 '11 at 15:25
  • 3
    So, is the selected answer here compliant with this Rails 3 asset pipeline model? – MattSlay Mar 06 '12 at 18:15
  • 2
    @MattSlay See this: http://railsapps.github.com/rails-javascript-include-external.html#specific Read through the page-specific part, then go down a little way to read more about how to get your js to only execute on the right pages. – Christian Bankester Jan 31 '13 at 16:31
12

I suggest putting it all into one file, which you can then minify and gzip. The client will only have to download it once, as it'll be cached on all subsequent requests.

Another thing that might interest you is sprockets, a javascript dependency manager, which you can install using gem. You can get more information on sprockets from the website (http://getsprockets.org/) or from the github page (https://github.com/rails/sprockets). It makes writing big javascript applications much more manageable.

Denis Tsoi
  • 9,428
  • 8
  • 37
  • 56
jonnii
  • 28,019
  • 8
  • 80
  • 108
6

This changes with Rails 3.1 and the asset pipeline!!!

Separate files are best as you indicate. The issues about how to reference them all and link them goes away with rails 3.1 which aims to compile them all into single files for production.

Michael Durrant
  • 93,410
  • 97
  • 333
  • 497
2

One can use Jammit to include css and javascripts files

for detail: http://documentcloud.github.com/jammit/

Use:

step 1:

Add js-files in assets.yml (see code below)

javascripts:

footer:

- app/javascripts/lib/*.js
- app/javascripts/jquery-plugins/*.js
- app/javascripts/custom/*.js
- app/javascripts/application.js

header:

- app/javascripts/core/*.js
- app/javascripts/head/*.js

step 2:

Add simple code in application layout:

<%= include_javascripts :header %>
<%= include_javascripts :footer %>
Leo
  • 37,640
  • 8
  • 75
  • 100
Omer Aslam
  • 4,534
  • 6
  • 25
  • 24
-2

maybe you want to use application_helper

def javascript(*files)
  content_for(:head) { javascript_include_tag(*files) }
end

def stylesheet(*files)
  content_for(:head) { stylesheet_link_tag(*files) }
end
dc10
  • 2,160
  • 6
  • 29
  • 46