Search code examples
requirejsundefinedmarionettecircular-dependency

requirejs returns undefined without dependency


On some occasions, requirejs returns an undefined object to my module. I've looked at a number of posts and most of the answer are related to circular dependencies. However I could find none (I have checked several times). I apologize by advance for pasting a quantity of code that I've tried to reduced to the minimum :) Any help would be greatly appreciated!

Here is the module init_app.js that fails:

define([
  'marionette',
], function(
    Marionette
) {
  "use strict";

  var App;
  App = new Marionette.Application();
  App.addRegions({ body: "#main_body" });
  return App;
});

Sometimes the Marionette module is undefined. Here is the part of my config.js that might be relevant:

define([], function() {
  'use strict';
  require.config({
    baseUrl: 'js',
    paths : {
      underscore : 'vendors/underscore/underscore',
      jquery : 'vendors/jquery/dist/jquery',
      backbone : 'vendors/backbone/backbone',
      marionette : 'vendors/marionette/lib/backbone.marionette',
      wreqr : 'vendors/backbone.wreqr/lib/backbone.wreqr',
      eventbinder : 'vendors/backbone.eventbinder/lib/backbone.eventbinder',
      babysitter : 'vendors/backbone.babysitter/lib/backbone.babysitter',
    },
    shim : {
      jquery : {
        exports : 'jQuery'
      },
      underscore : {
        exports : '_'
      },
      backbone : {
        deps : ['jquery', 'underscore'],
        exports : 'Backbone'
      },
      wreqr: {
        deps : ['backbone'],
        exports: 'Backbone.Wreqr'
      },
      eventbinder : {
        deps : ['backbone']
      },
      babysitter : {
        deps: ['backbone']
      },
      marionette : {
        deps: ['backbone', 'wreqr', 'eventbinder', 'babysitter'],
        exports : 'Marionette'
      },
    }
  });
});

The main.js file is

require(['config'], function() {
  require( ['app'], function (App) {
    App.start({});
  });
});

where the app.js file is

define([
  'init_app',
  'router',
], function(
    App,
    Router
  ) {
  "use strict";

  App.on('start', function() {
    new Router();
    Backbone.history.start();
  });
  return App;
});

And the router will define a bunch of things that might depend on init_app.js. I've been especially carefull that none of them defines the app.js, which should be sufficient to guaranty that no circular dependency could cause this bug. Any clue??


Solution

  • You should review your shim configuration to remove all those shims that you've put in for modules that actually use define. For instance, jQuery uses define and thus does not need a shim. The same is true of Marionette. I've just installed it with Bower and found this towards the start of the file:

     if (typeof define === 'function' && define.amd) {
        define(['backbone', 'underscore'], function(Backbone, _) {
          return (root.Marionette = root.Mn = factory(root, Backbone, _));
        });
      }
      ...
    

    If you see something like this in a module you use, or a flat out call to define, then you should not use a shim for it.

    I've not checked every single module you use. Please review all of them to make sure you do not use shims where not needed. If you use shims incorrectly, you can get undefined values for your modules.