requireJS optional dependency

Matteo Pagliazzi picture Matteo Pagliazzi · Jan 4, 2013 · Viewed 10.2k times · Source

I'm adding AMD support to a javascript library I develop.

This library may use jquery but it will still work if jquery isn't loaded.

When defining the module dependency there's a way to set a dependency as 'optional' so that if that library is missing the module will still work?

Answer

LordOfThePigs picture LordOfThePigs · Dec 11, 2014

I've had exactly the same problem recently, and here's how I fixed it. I defined a RequireJS plugin called optional which ignores modules that fail to load by explicitly defining them as an empty object (but I suppose you could also define it as null or anything else if you wanted).

Here is the code (tested with RequireJS 2.1.15):

define("optional", [], {
    load : function (moduleName, parentRequire, onload, config){

        var onLoadSuccess = function(moduleInstance){
            // Module successfully loaded, call the onload callback so that
            // requirejs can work its internal magic.
            onload(moduleInstance);
        }

        var onLoadFailure = function(err){
            // optional module failed to load.
            var failedId = err.requireModules && err.requireModules[0];
            console.warn("Could not load optional module: " + failedId);

            // Undefine the module to cleanup internal stuff in requireJS
            requirejs.undef(failedId);

            // Now define the module instance as a simple empty object
            // (NOTE: you can return any other value you want here)
            define(failedId, [], function(){return {};});

            // Now require the module make sure that requireJS thinks 
            // that is it loaded. Since we've just defined it, requirejs 
            // will not attempt to download any more script files and
            // will just call the onLoadSuccess handler immediately
            parentRequire([failedId], onLoadSuccess);
        }

        parentRequire([moduleName], onLoadSuccess, onLoadFailure);
    }
});

You can then require a module optionally using simply

require(['optional!jquery'], function(jquery){...});

knowing that if the jquery module could not be loaded, the parameter passed to your callback function will be an empty object.