This is one of the most confusing things to deal with when starting up in Node and Mongoose.
When you require('mongoose') for the first time, it creates a singleton instance of Mongoose - the same instance is returned each time you need it.
This simplifies the job, but it's a bit of โmagicโ that is hard to understand at the beginning.
This means that when you call mongoose.connect("127.0.0.1", "todomvc", 27017); in app.js, it creates a connection that is saved with the application.
It also means mongoose.model('Todo', TodoSchema); makes the Todo model available in any other area that calls require('mongoose') through mongoose.model('Todo') . It can be var'd at the top of another file that you require , as in the example above, or at the moment when you need it in the middle of the callback.
This is how you get the Todo model into your .js routes, and a very good reason to tell Mongoose about your models is one of the first things you do in your application.
To answer your questions regarding areas of understanding; each require file has its own scope and does not have access to anything other than global objects such as a process. You must require everything you want to work with, and you can only pass variables by calling functions or creating classes that are displayed through the exports object.
Thus, for the actual example above, there is no use in exporting a model from models.js, since it is not mentioned later in the application. where models.js is required. These are the lines in routes.js that make the Todo model available:
var mongoose = require('mongoose') , Todo = mongoose.model('Todo');
How Todo exists on this line:
crudUtils.initRoutesForModel({ 'app': app, 'model': Todo });
There is also no use (as far as I know) for wrapping routes in an anonymous function, since this is essentially provided by require .