Namespaces in node.js with requirement

I play and learn about vows with a personal project. This is a small client library, with validation done in vows. Therefore, I have to create and test a file that is written as follows:

(function(exports) { var module = export.module = { "version":"0.0.1" }; //more stuff })(this); 

In my testing (based on science.js , d3, etc.) the following module is required:

 require("../module"); 

I kept getting the “module undefined error” when trying to run the tests, so I went to repl and ran:

 require("../module") 

and he returned:

 { module: { version: "0.0.1" } } 

I understand that I can do something like:

 var module = require("../module").module; 

but I feel that I am creating a problem by doing it this way, especially since the libraries on which I based this project do it in the format I described.

I would like my project to behave in the same way as I, based on it, where:

 require("../module"); 

creates a variable in this namespace:

 module.version; //is valid. 

I saw this in different libraries, and I follow the format and thought process in T, but I think I can skip something, requiring behavior that I don't know about.

+8
require vows
source share
1 answer

There is no problem creating this method. Modules determine what they return in the module.exports object. By the way, you don’t really need self-executing functions (SEF), there is no global leak in browsers :-)

Examples

module1.js:

 module.exports = { module: { 'version': '0.1.1' } }; 

main.js:

 var module1 = require( './module1.js' ); // module1 has what is exported in module1.js 

Once you understand how this works, you can easily export the version number right away if you want:

module1.js:

 module.exports = '0.1.1'; 

main.js:

 var module1 = require( './module1.js' ); console.log( module1 === '0.1.1' ); // true 

Or, if you need logic, you can easily expand your module1.js file as follows:

 module.exports = ( function() { // some code return version; } () ); // note the self executing part :-) // since it self executed, the exported part // is what returned in the SEF 

Or, like many modules, if you want to export some utility functions (and keep others "private"), you can do this as follows:

 module.exports = { func1: function() { return someFunc(); }, func2: function() {}, prop: '1.0.0' }; // This function is local to this file, it not exported function someFunc() { } 

So in main.js:

 var module1 = require( './module1.js' ); module1.func1(); // works module1.func2(); // works module1.prop; // "1.0.0" module1.someFunc(); // Reference error, the function doesn't exist 

Your special occasion

In your special case, I would not recommend doing it as if they were doing.

If you look here: https://github.com/jasondavies/science.js/blob/master/science.v1.js

You see that they do not use the var keyword. So they create a global variable .

This is why they can access it if they require module that defines a global variable.

And by the way, the exports argument is useless in their case. This is even misleading, since it is actually a global object (equivalent to window in browsers), and not a module.exports object ( this in functions is a global object, it will be undefined if strict mode has been enabled).

Conclusion

Don't do as if they do, this is a bad idea. Global variables are a bad idea, it is better to use the philosophy of node and store the necessary module in a variable that you reuse.

If you want to have an object that can be used on the client side and tested in node.js, follow these steps:

yourModule.js:

 // Use either node export or the global object in browsers var global = module ? module.exports : window.yourModule; ( function( exports ) { var yourModule = {}; // do some stuff exports = yourModule; } ( global ) ); 

What you can shorten to this to avoid creating a global variable:

 ( function( exports ) { var yourModule = {}; // do some stuff exports = yourModule; } ( module ? module.exports : window.yourModule ) ); 

So you can use it like this on the client side:

 yourModule.someMethod(); // global object, "namespace" 

And on the server side:

 var yourModule = require( '../yourModule.js' ); yourModule.someMethod(); // local variable :-) 

Just FYI, .. means "parent directory". This is the relative way to get the module. If the file was in the same directory, you should use . .

+16
source share

All Articles