9

I'm trying to define a module with conditional dependencies (depending on Modernizr test). I've done something that works but feel hacky to me.

Can you tell me what you think and if there is a better way to do it? Thanks.

var dependencies = ["jquery"];

require(["modernizr"], function() {
  if(Modernizr.canvas) dependencies.push("modernizr/excanvas");
});

define(dependencies, function($) {

  $(function() {
    // code here
  });

});
karellm
  • 1,843
  • 1
  • 20
  • 23
  • I don't have the time to find a reference right now, and I may be confused, but its my impression that you cannot have variable dependencies with `define`. Does `require()` work? – Zach Lysobey Apr 03 '13 at 20:30

3 Answers3

3

You are trying to just load that file up when a browser doesn't support something, load more javascript to make it sorta work type scenario?

Or I could see you trying to implement the same feature using different methods based upon wether the method is available or not, and want to load in additional or alternative javascript based on that condition.

Still, bear with me here I'm making assumptions and I haven't tried this exactly but the theory makes sense maybe :)

Perhaps something along the lines of

define("jquery","modernizr", function($) {
  $(function() {
    var functionMain = function() {
      // code here
    }

    var functionA = require(["modernizr/excanvas"], function() {
      functionMain()
    });    
    //require here not strictly necessary
    var functionB = require([""], function() {
      functionMain() 
    });    


    if(Modernizr.canvas)
      functionA();
    else
      functionB()
  }); 
});

I don't know, perhaps just a matter of style or preference, this is just another way of doing the same thing really but without the dependences array which I just took a dislike to (lol) though really there's probably nothing wrong with it if all you want to do is load that file in conditionally and the rest of the code is the same

I got thinking more about splitting implementations up based on a condition and then having different conditional requires per implementation, still its all opinion eh? :)

Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
PJUK
  • 1,758
  • 1
  • 16
  • 21
  • Hi Phil, you totally got it. I would definitely use you way if there is code based on the test but it wasn't my case. I just needed to laod or not the dependency. Thanks for your input! – karellm Dec 11 '11 at 05:11
1

Modernizr isn't currently wrapped in an 'amd' define function. In order to get modernizr to load in as a module for require.js you would need to hack modernizr.js as follows:

FOR modernizr.js

CUT:

;window.Modernizr = function

REPLACE WITH:

define('Modernizr',function(){
;Modernizr = function

ADD THIS TO THE BOTTOM

return Modernizr;
});
Jason Sturges
  • 15,855
  • 14
  • 59
  • 80
steve
  • 31
  • 2
  • 3
    The semicolon at the front of ";Modernizr" can be omitted since you've now put it inside a function. The initial semicolon only makes sense if it's the first thing in the file - just makes sure the previous statement has completed in case someone had some poorly written javascript – Matt Browne May 23 '12 at 21:59
  • @Matt i think you can also omit the 'Modernizr' part and return part as you are declaring Modernizr in the global space. – Nicola Peluchetti Jun 25 '12 at 17:02
  • 2
    Thanks but it doesn't answer the question. It is not about AMD-ify Modernizr but having conditional dependencies. – karellm Jul 11 '12 at 23:49
  • 2
    You can set up a shim for Modernizr in your requirejs config so you don't have to modify modernizr.js – wprl Dec 16 '12 at 23:43
  • 2
    Use shim config to make Modernizr AMD friendly. See http://requirejs.org/docs/api.html#config-shim – Elmer Feb 22 '13 at 03:06
1

You can actually do two things, it depends if you want to add a global variable or you don't. In any case you create a modernizr.js file and if you want to create a global variable

define( function() {
    /* Modernizr 2.5.3 (Custom Build) | MIT & BSD
     * Build: http://modernizr.com/download/#-touch-cssclasses-teststyles-prefixes-load
     */
    Modernizr = (function( window, document, undefined ) {
        // all your modernizr code

        return Modernizr;

    })(window, window.document);// Be careful to change this with window
} );// This closes the define call

then you can simply

require( ['modernizr'], function() {
    // Here the script has loaded and since you  added a global variable, use that
    if(!Modernizr.borderradius){ 
});

if you don't want to add a global variable, you should do

define( function() {
    /* Modernizr 2.5.3 (Custom Build) | MIT & BSD
     * Build: http://modernizr.com/download/#-touch-cssclasses-teststyles-prefixes-load
     */
    // Change the name of the variable so you don't have scope issues
    var modernizr = (function( window, document, undefined ) {
        // all your modernizr code

        return Modernizr;

    })(window, window.document);// Be careful to change this with window
    // Return your variable
    return modernizr;
} );// This closes the define call

and then

require( ['modernizr'], function( Mdzr ) {
    // Here the script has loaded and you assigned the return value of 
    // the script to the variable Mdzr so use that
    if(!Mdzr.borderradius){ 
});
Nicola Peluchetti
  • 76,206
  • 31
  • 145
  • 192
  • 1
    Thanks but it doesn't answer the question. It is not about AMD-ify Modernizr but having conditional dependencies. – karellm Jul 11 '12 at 23:49