Nathan Long
Nathan Long

Reputation: 125902

Can Rails' javascript_include_tag ignore previously-loaded scripts?

I'm using this line:

= javascript_include_tag :all, :recursive => true, :cache => true

in the footer of a Rails app to do the following:

However, I want to load one of these scripts in the head, because some inline JS depends on it.

Is there an option for javascript_include_tag to exclude files that have already been loaded?

I know it doesn't do this by default, because right now I see a script referenced twice in the source HTML.

Upvotes: 3

Views: 1927

Answers (2)

hornairs
hornairs

Reputation: 1725

javascript_include_tag is a simple html helper and doesn't track weather or not something has already been included on the page, so no, there isn't an option, sucks.

In place of this, you can solve your problem in a few ways:

  1. Use something like Jammit, which I use right now and is an absolute joy. It packages all your javascripts up in production into one file, allows you to compress the shit out of them, and does the same for CSS. You configure it using a .yml file in your config directory, making it portable and easy to recursively include scripts from directories while still controlling the order in which they are included on the page or appended to the package. An alternative (less awesome IMHO) to Jammit is Asset Packager.

  2. Use javascript_include_tag in the head. Not really the end of the world. Optimize later.

  3. Not really Rails specific, but use head.js. head.js is pretty new but allows you to load many scripts quickly, in parallel, while preserving the execution order and taking callbacks to fire once your scripts are loaded but before the dom is ready. It includes a bunch of other goodies like HTML5 friendliness in older browsers. This option is interesting because you keep your scripts separate, or at least in different packages for maximum parallel download speed. I'm not sure weather or not downloading one huge compressed package serially in the <head> or even right at the footer, or loading things in parallel using head.js will be faster, but it sure makes managing these things easier.

I've used both head.js and Jammit recently and I must say, for heavy Javascript apps, they make things wonderfully easy.

Upvotes: 4

Scott
Scott

Reputation: 17247

In config/application.rb you can set the meaning of :defaults in the javascript_include_tag :

# JavaScript files you want as :defaults (application.js is always included).
config.action_view.javascript_expansions[:defaults] = %w(rails, jquery)

You can then use the :defaults parameter to use the tag in application.erb.html, or wherever you like:

<%= javascript_include_tag :defaults %>

Once you've done this at the bottom of your view template, you can of course include single scripts before it.

Now, I realise that you wanted to use the :all parameter, and load recursively, but this solution does give you more control, which I think you are going to need here.

Upvotes: 1

Related Questions