Conditional javascript require in the asset pipeline

3.4k views Asked by At

I'm struggling with the asset pipeline. I'm loading dojo from Google CDN putting this in my template:

= javascript_include_tag 'http://ajax.googleapis.com/ajax/libs/dojo/1.6.1/dojo/dojo.xd.js', :'data-dojo-config' => %Q(dojoBlankHtmlUrl:'/blank.html', baseUrl: 'assets/', modulePaths: {custom: 'javascripts/modules'})

I just want a fallback to a local version if running locally or if the CDN is down. I thought of doing this:

script typeof(dojo) === "undefined" && document.write(unescape('%3Cscript src="js/libs/dojo-1.6.1.min.js"%3E%3C/script%3E'));

But I don't like it as it works out of the asset pipeline. I want to keep dojo in vendors/assets/javascripts/dojo. How can I get the fallback to be served by the asset pipeline.

Is there a way do declare conditional require in the asset pipeline. What I want is to run some javascript tests, and depending on the result serve a file.

Thanks

2

There are 2 answers

0
karellm On BEST ANSWER

Thanks Richard!

I don't want to have yepnope to load one library. It would be overkill imo. Here is the solution I came up with, based on your help (written in slim):


1/ In vendors/assets/javascripts/, I have my dojo.js.

2/ In config/application.rb:

# Precompile these assets files
config.assets.precompile += ['dojo.js']

3/ In the template:

= javascript_include_tag "http://ajax.googleapis.com/ajax/libs/dojo/#{Settings.dojoVersion}/dojo/dojo.xd.js", :'data-dojo-config' => %Q(dojoBlankHtmlUrl:'/blank.html', baseUrl: 'assets/', modulePaths: {custom: 'javascripts/modules'})
script = "typeof(dojo) === \"undefined\" && document.write(unescape('%3Cscript src=\"#{asset_path('dojo')}\"%3E%3C/script%3E'));".html_safe

I also posted on the Rails Google Group to request the addition of two options to the javascript_include_tag, :test and :local that would take care of all the work. We'll see.

0
Richard Hulse On

I suggest you use yepnope, a lightweight library for loading libraries like this in parallel (for speed) and it gives you the option to run some other code to test if the library is loaded. For example:


yepnope([{
  load: 'http://ajax.googleapis.com/ajax/libs/dojo/1.6.1/dojo/dojo.xd.js',
  complete: function () {
    if (!window.jQuery) {
      yepnope('asset_path('you_local_copy_of_dojo') ');
    }
  }
}])

(Note: You will need erb tags around the asset_path helper)

The local dojo file would be in the assets/javascript folder, but not included in the application manifest. You need to add the dojo file to the precompile array:

config.assets.precompile += 'your_local_file.js'

And this will make it available to the asset_path helper.