55

I'm working on a project with Node.js and the server-side code is becoming large enough that I would like to split it off into multiple files. It appears this has been done client-side for ages, development is done by inserting a script tag for each file and only for distribution is something like "Make" used to put everything together. I realize there's no point in concatting all the server-side code so I'm not asking how to do that. The closest thing I can find to use is require(), however it doesn't behave quite like script does in the browser in that require'd files do not share a common namespace.

Looking at some older Node.js projects, like Shooter, it appears this was once not the case, that or I'm missing something really simple in my code. My require'd files cannot access the global calling namespace at compile time nor run time. Is there any simple way around this or are we forced to make all our require'd JS files completely autonomous from the calling scope?

Matt Molnar
  • 2,412
  • 3
  • 22
  • 28

2 Answers2

70

You do not want a common namespace because globals are evil. In node we define modules

// someThings.js

(function() {
    var someThings = ...;

    ...

    module.exports.getSomeThings = function() {
        return someThings();
    }

}());

// main.js

var things = require("someThings");
...
doSomething(things.getSomeThings());

You define a module and then expose a public API for your module by writing to exports.

The best way to handle this is dependency injection. Your module exposes an init function and you pass an object hash of dependencies into your module.

If you really insist on accessing global scope then you can access that through global. Every file can write and read to the global object. Again you do not want to use globals.

sameers
  • 4,855
  • 3
  • 35
  • 44
Raynos
  • 166,823
  • 56
  • 351
  • 396
  • Thanks for the info, marking as correct. I generally agree with the globals == evil concept but it seems they do have their place. What if, for instance, I have a base property that I want to set for a given "class" that depends on a value elsewhere? Ex: `SomeClass.prototype.baseProp = SomeOtherClass.prototype.prop * 2;` In this case, I'm either forced to set this at object instantiation via the constructor, or, use the `global` object as you suggested. I think the later may be the most proper. – Matt Molnar Apr 18 '11 at 14:18
  • 3
    @XHR Then `SomeClass` has a dependency on `SomeOtherClass` and you `require("SomeOtherClass")` inside SomeClass.js. I have a single global variable in my code. `global._ = require("underscore")` because I use it _every_ single file. That's the only usecase for `global`. – Raynos Apr 18 '11 at 15:30
44

re @Raynos answer, if the module file is next to the file that includes it, it should be

var things = require("./someThings");

If the module is published on, and installed through, npm, or explicitly put into the ./node_modules/ folder, then the

var things = require("someThings");

is correct.

Community
  • 1
  • 1
michielbdejong
  • 1,077
  • 9
  • 14
  • 4
    If you are requiring an actual node module (installed via npm, installed under PROJECT_ROOT/node_modules), then the second line of code is needed. If you are requiring your own file (i.e. ROOT_DIR/models/thing.js), you need to do the first line of code (though you can strip the .js extension away). – Ankit Aggarwal Jul 05 '12 at 17:46
  • I'm not positive, but you may be able to alter this behavior using the [extensions property of the require object](http://nodejs.org/api/globals.html#globals_require_extensions). – snapfractalpop May 14 '13 at 17:41