This is possible, but depends heavily upon how you structure your JS application. Also, I'm assuming you have a Backbone app here. There are different approaches for different frameworks.
For instance, you may have an app.js
that looks something like this:
define([
'DvdItemView', 'DvdModel', 'DvdCollection',
'BookItemView', 'BookModel', 'BookCollection'
], function(DvdView, DvdModel, DvdCol, BookView, BookModel, BookCol) {
// router declarations go here
});
Because you 'define' this module as depending upon the above modules, they will always be loaded before running the router code. As @alexndm points out, if you run r.js on this you can actually combine all of your modules into one.
However as you mention, once the application gets to be a certain size what you want is to lazy-load different parts depending upon what the user is interacting with. This is more of an application concern, and RequireJS can only help you so much in this regard. I believe the best way to do this is in the router.
routes: {
'/books': 'booksList',
'/books/:id': 'booksDetail',
'/dvds': 'dvdList',
'/dvds/:id': 'dvdDetail'
},
booksList: function() {
if (!booksDepsLoaded) {
// Here we go and load the appropriate files
require(['BooksArea'], function(BooksArea) {
// BooksArea.Model, BooksArea.Collection, etc...
// do stuff to render a book list..
})
}
},
...
This is very naive pseudo code. You will likely want to write some generic code to handle routes that still need dependencies to be loaded, and error handling, etc.
The important concept to grasp though, is you need to have the routes defined before the application/router is started - and then you need async code to handle fetching modules.