12

I just started using a new version of Express (2.5.5) that by default creates a ./routes directory along with ./views and ./public

Inside of routes there is a index.js file which contains:

/*
 * GET home page.
 */

exports.index = function(req, res){
  res.render('index', { title: 'Express' })
};

by default (after running express from the commandline) and this is the routes section in the main app.js:

// Routes

app.get('/', routes.index);

I've set up a variable for a redis client in the main app.js:

var redis = require('redis'),
    db = redis.createClient();

and I was wondering how I could access the methods of db (and whatever other modules I require in app.js) in the files contained in ./routes

Cœur
  • 37,241
  • 25
  • 195
  • 267
nak
  • 3,077
  • 3
  • 27
  • 35
  • I don't know whether this is a good practice, but you could have your modules wrapped inside an `exports.init` function which takes the shared instances as arguments. That function would return the actual export functions, and you require the file like `var routes = require("./routes/").init(db);`. – pimvdb Jan 19 '12 at 18:37

3 Answers3

21

I really liked Jamund's solution, but I would extend the concept to this:

// db.js
var redis = require('redis');
module.exports = redis.createClient();

// index.js
var db = require(.'/db')

// whatever other file
var db = require(.'/db')
// do something with db
db.disconnect();

both db on index and other file would get the same instance of the redis client

Marcel M.
  • 2,376
  • 2
  • 18
  • 24
  • Would you then have to export every redis function you want to use? example: redis.set("some key", "some val"); or redis.get("missingkey", function(err, reply) { // reply is null when the key is missing console.log(reply); }); etc. – asiammyself Dec 16 '13 at 16:23
  • @asiammyself what do you mean by export? you would be able to call `db.set(key, val)` or `db.get(key, fn)` from your other files. – Marcel M. Dec 16 '13 at 19:32
  • like so: module.exports { get: redis.get() set: redis.set } but you made it clear they would work so no worries. – asiammyself Dec 16 '13 at 19:38
5

Just call this at the top of your files. Requires are in a shared space, so you can re-require the file multiple times and it will always reference the same version. If you want to be fancy you can create your own db module that does something like this, to prevent double creating clients:

// db.js
var db 
var redis = require('redis')
exports.connect = function() {
  if (!db) db = redis.createClient()
  return db
}

exports.disconnect = function() {
  redis.quit()
  db = null
}


// index.js
var dbHelper = require(.'/db')
var db = dbHelper.connect()

// whatever other file
var dbHelper = require(.'/db')
var db = dbHelper.connect() // won't connect twice
Jamund Ferguson
  • 16,721
  • 3
  • 42
  • 50
3

You can either create an app global and hang the vars you want to share off that or you can use an initializer function in your routes file

f.e.

// app.js

var app = express.createServer()
  , db = require('redis').createClient();

require('./routes').with(app, db);

// routes.js
module.exports.with = function(app, db) {
  app.get('/',function(r,s) { s.end('Sweet');});
}
deedubs
  • 282
  • 1
  • 6