I am playing around and learning about vows with a personal project. This is a small client side library, with testing done in vows. Therefore, I must build and test a file that is written like this:
(function(exports) {
var module = export.module = { "version":"0.0.1" };
//more stuff
})(this);
In my testing (based off of science.js, d3, etc.) requires that module like so:
require("../module");
I continued to get a “module not defined error” when trying to run the tests, so I went to a repl and ran:
require("../module")
and it returned:
{ module: { version: "0.0.1" } }
I realize I could do something like:
var module = require("../module").module;
but feel like I am creating a problem by doing it that way, especially since the libraries that I based this project on are doing it in the format I described.
I would like for my project to behave similar to those which I based it off of, where:
require("../module");
creates a variable in this namespace:
module.version; //is valid.
I have seen this in a variety of libraries, and I am following the format and thought process to the T but believe I might be missing something about require behavior I don’t know about.
There is no problem creating it this way. Modules define what they return in the
module.exportsobject. By the way, you don’t actually need self executing functions (SEF), there is no global leakage like in browsers 🙂Examples
module1.js:
main.js:
Once you’ve understood how this works, you can easily export the version number right away if you want to:
module1.js:
main.js:
Or if you want some logic, you can easily extend your
module1.jsfile like this:Or, as many modules do, if you want to export some utility functions (and keep others “private”), you could do it like this:
So, in main.js:
Your special case
About your special case, I wouldn’t recommend doing it like they’re doing.
If you look here: https://github.com/jasondavies/science.js/blob/master/science.v1.js
You see that they’re not using the
varkeyword. So, they’re creating a global variable.This is why they can access it once they
requirethe module defining the global variable.And by the way, the
exportsargument is useless in their case. It’s even misleading, since it actually is theglobalobject (equivalent ofwindowin browsers), not themodule.exportsobject (thisin functions is the global object, it’d beundefinedif strict mode were enabled).Conclusion
Don’t do it like they’re doing, it’s a bad idea. Global variables are a bad idea, it’s better to use node’s philosophy, and to store the required module in a variable that you reuse.
If you want to have an object that you can use in client side and test in node.js, here is a way:
yourModule.js:
Which you can shorten to this in order to avoid creating the
globalvariable:This way, you can use it like this on the client-side:
And on the server side:
Just FYI,
..means “parent directory”. This is the relative path of where to get the module. If the file were in the same directory, you’d use..