Requirejs plus Backbone?

Hey guys! I’m starting my first backbone application with requirejs and it’s not working. I’m not sure i’m doing it correctly, but i’m trying to access the route variable but it’s not working…Here’s the code:

Hi calebbee,

At the moment, you’re setting up your router object like this:


var router = Backbone.Router.extend({

    routes:{
        '' : 'index'
    },

});

var app_router = new router;

app_router.on('index', function(){
    console.log( "hi there from" );
});

You’ve defined your index route correctly, but you’re trying to listen for an ‘index’ event on the router which doesn’t exist. Your route actions need to be methods of your router object, like this:


var router = Backbone.Router.extend({

    routes:{
        '' : 'index'
    },

    index: function() {
        console.log( "hi there from" );
    }

});

Looking over the rest of your code, there are several other things that need changing:
main.js


requirejs.config({  //This should be require.config
  "paths":{
		"underscore":"//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.4.4/underscore-min",
		"jquery": "//cdnjs.cloudflare.com/ajax/libs/jquery/2.0.1/jquery.min",
		"backbone": "//cdnjs.cloudflare.com/ajax/libs/backbone.js/1.0.0/backbone-min"
	},
	"config":{ //Remove this config object - shim should be on the same level as paths
		shim: {
			    underscore: {
			      exports: '_'
			 },
		backbone: {
			      deps: ['underscore', 'jquery'],
			      exports: 'Backbone'
			 }
		}
	}
});

define(['underscore','jquery', 'backbone', 'router'], //This should be a require call, not define
function($, _, Router){  //Your dependencies are out of order with the variables you're passing into the function

	Router.initialize(); //Create a new instance of your router object here, and the initialize method is called automatically by Backbone
});

So, with these changes, the revised file should look like:


require.config({
    "paths": {
        "underscore":"//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.4.4/underscore-min",
        "jquery": "//cdnjs.cloudflare.com/ajax/libs/jquery/2.0.1/jquery.min",
        "backbone": "//cdnjs.cloudflare.com/ajax/libs/backbone.js/1.0.0/backbone-min"
    },
    shim: {
        underscore: {
            exports: '_'
        },
        backbone: {
            deps: ['jquery', 'underscore'],
            exports: 'Backbone'
        }
    }
});

require(['router'], function(Router) {
    var app_router = new Router;
    Backbone.history.start();
});

Note that to start the router, we only need to state router as a dependency - router itself defines Backbone as a dependency, and we’ve already told requirejs that Backbone depends on underscore and jquery.

The revised router.js now looks like this:


define(['backbone'], function(){

    var router = Backbone.Router.extend({

        routes:{
            '' : 'index'
        },

        index: function() {
            console.log( "hi there from" );
        }

    });

    return router;

});

Ah, okay. I was researching and just put the shim in my code without knowing what it really does. But now i see what’s going on. The export option just defines how you’re going to reference it in the code right? It allows you to use _ for underscore? If so, why don’t you need it for jquery?

The shim is for code that doesn’t use the AMD module system… jquery does, which is why you don’t need a shim for it. The export option tells requirejs what global variable the code uses. In the case of underscore, you access all of the features of the library via the _ global variable. That’s why when you’re defining your own modules, like router, you don’t have to pass in Backbone and $ as function arguments - they’re already available in the global scope.