Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

requireJS optional dependency

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?

like image 350
Matteo Pagliazzi Avatar asked Jan 04 '13 20:01

Matteo Pagliazzi


People also ask

Is RequireJS still relevant?

RequireJS has been a hugely influential and important tool in the JavaScript world. It's still used in many solid, well-written projects today.

What is RequireJS used for?

RequireJS is a JavaScript library and file loader which manages the dependencies between JavaScript files and in modular programming. It also helps to improve the speed and quality of the code.

What is a RequireJS module?

RequireJS loads each dependency as a script tag, using head. appendChild(). RequireJS waits for all dependencies to load, figures out the right order in which to call the functions that define the modules, then calls the module definition functions once the dependencies for those functions have been called.

What is Shim RequireJS?

As per RequireJS API documentation, shim lets you. Configure the dependencies, exports, and custom initialization for older, traditional "browser globals" scripts that do not use define() to declare the dependencies and set a module value. - Configuring dependencies.


2 Answers

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.

like image 78
LordOfThePigs Avatar answered Sep 28 '22 11:09

LordOfThePigs


You cannot really set it optional, but you can catch the error and unload the module using undef:

require(['jquery'], function ($) {     //Do something with $ here }, function (err) {     //The errback, error callback     //The error has a list of modules that failed     var failedId = err.requireModules && err.requireModules[0];     if (failedId === 'jquery') {         //undef is function only on the global requirejs object.         //Use it to clear internal knowledge of jQuery. Any modules         //that were dependent on jQuery and in the middle of loading         //will not be loaded yet, they will wait until a valid jQuery         //does load.         requirejs.undef(failedId);         ...      } }); 

Full example here.

like image 22
asgoth Avatar answered Sep 28 '22 11:09

asgoth