4

Let's say I have the following app.js (obviously very simplified):

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

// include routes
require('./lib/routes')(app);

// some random function
var foo = function() {
    return 'bar';
};

// another random function
var foo2 = function() {
    return 'bar2';
};

And then I have the routes module:

module.exports = function(app){
    app.get('/some/route', function(req, res){
        var fooBar = foo(),
            fooBar2 = foo2();

        res.end(fooBar + fooBar2);
    });
};

This obviously doesn't work since foo and foo2 weren't defined within the module. Is there a way to make this work, or at least a different pattern to better accomplish what this?

1 Answer 1

7

Well you can just put these two functions in an object and pass them on the initialization of the routes.js .

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

// some random function
var foo = function() {
    return 'bar';
};

// another random function
var foo2 = function() {
    return 'bar2';
};

var fns = {foo : foo, foo2: foo2}

// include routes
require('./lib/routes')(app, fns);

in routes:

module.exports = function(app, fns){
    app.get('/some/route', function(req, res){
        var fooBar = fns.foo(),
            fooBar2 = fns.foo2();

        res.end(fooBar + fooBar2);
    });
};

This is how would I do it. You can also include them in the app object. Beside passing them in init functions, you can also export those two functions and require them in routes.js.

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

// some random function
var foo = function() {
    return 'bar';
};

// another random function
var foo2 = function() {
    return 'bar2';
};

module.exports = {foo : foo, foo2: foo2}

// include routes
require('./lib/routes')(app, fns);

in routes:

module.exports = function(app){
    var fns = require('../app.js');
    app.get('/some/route', function(req, res){
        var fooBar = fns.foo(),
            fooBar2 = fns.foo2();

        res.end(fooBar + fooBar2);
    });
};

But I don't like the idea of it, since it makes circular dependencies. Don't have any good feelings about them.

Sign up to request clarification or add additional context in comments.

6 Comments

Both the original question, and this accepted answer imply that module.exports is a function that is called. It's not. It's an object that contains functions. Also both the question and this answer have a trailing ")" after the closing brace for the definition. Eg module.exports = function(app){..}) - For one thing this would never execute. For another, it should be something like module.exports.myfunc = function(args) {...} OR module.exports = { myfunc1 : function(){...}, myfunc2: function(){...} }; Ok it's an old question, but for the sake of newbies, it needs clarification.
The closing brace was a mistake. module.exports can be set to a function. It's called substack pattern unofficially. Check it out.
i realize it can be set to anything you like, including a random number. it all depends if you want to follow a standard, or just hack about, not caring if anyone wants to use your code. you could after all just not use modules at all. the whole point is to follow a convention. if you were planning on doing that, an acceptable way would be to export an object or function called substack, which does whatever you want.
as an experiment, try this: "console.log(module);" see what it prints out. its has an empty {} for exports. that's the standard. you then go ahead and populate it, not blow it away and replace it with a function/number/string/date object. if you need to export other things, put them inside the exports object. that's how it's been designed to be be used.
Actually whenever you want to export one function only, this method is used. In some cases, I've seen people adding properties to the function(function main() {...};main.minorThing = function () {...}; module.exports = main). This is a very common pattern. Node.js assert module also exports a main function as I described above. Looking at the first page of npm registry, in the top modules, request, express, socket.io and mkdirp all use this pattern.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.