Conditional javascript require in the asset pipeline
Asked Answered
S

2

2

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

Segregate answered 17/10, 2011 at 16:23 Comment(3)
one of the best features of CDN is that it should be cached anyways by the client, so you should not bother about it beeing down. for local development you could just do a javascript_inlcude_tag then. if that solution is not save enough for you, you should put it into your assets/javascripts and serve it with your other js all time.Aubarta
I get that. But that'd be nice to have a way to process files through the asset pipeline without including them in the template. So you could generate a public/assets/javascripts/dojo-1.6.1.js file you can include through javascript. 1.6.1 would act as fingerptinting. The best of both worlds.Segregate
i don't think that it's a cool idea, but taste differs.Aubarta
S
1

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.

Segregate answered 18/10, 2011 at 2:41 Comment(0)
F
3

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.

Flash answered 17/10, 2011 at 17:43 Comment(0)
S
1

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.

Segregate answered 18/10, 2011 at 2:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.