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?
RequireJS has been a hugely influential and important tool in the JavaScript world. It's still used in many solid, well-written projects today.
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.
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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With