RequireJS - What is the purpose of the "exports" property in shim

Naresh picture Naresh · Dec 30, 2012 · Viewed 40.3k times · Source

What is the purpose of the "exports" property in the shim below? Is it really required?

requirejs.config({
    shim: {
        'backbone': {
            deps: ['underscore', 'jquery'],
            exports: 'Backbone'
        }
    }
});

I ask because it seems redundant - when the module is included in a dependency list, we will specify the exported name again as the function argument:

define(['backbone'], function (Backbone) {
  return Backbone.Model.extend({});
});

Answer

Simon Smith picture Simon Smith · Dec 31, 2012

If shim is not used in your example then the Backbone object you pass in as a parameter would be undefined as Backbone is not AMD compliant and does not return an object for RequireJS to use.

define(['backbone'], function (Backbone) {
  // No shim? Then Backbone here is undefined as it may
  // load out of order and you'll get an error when
  // trying to use Model
  return Backbone.Model.extend({});
});

To give a bit of context I will use the code that the r.js optimiser spits out but I will simplify it for this example. It helped me understand the point of it by reading what the optimiser produces.

The shimmed Backbone would be a little like this:

// Create self invoked function with the global 'this'
// passed in. Here it would be window
define("backbone", (function (global) {
    // When user requires the 'backbone' module
    // as a dependency, simply return them window.Backbone
    // so that properites can be accessed
    return function () {
        return global.Backbone;
    };
}(this)));

The point is to give RequireJS something to return back to you when you ask for a module, and it will ensure that is loaded first before doing so. In the case of the optimiser, it will simply embed the library before hand.