module.exports vs exports in Node.js
module.exports vs exports in Node.js
I've found the following contract in a Node.js module:
module.exports = exports = nano = function database_module(cfg) {...}
I wonder whats the different between module.exports
and exports
and why both are used here.
Answer by William for module.exports vs exports in Node.js
Setting module.exports
allows the database_module
function to be called like a function when require
d. Simply setting exports
wouldn't allow the function to be exported because node exports the object module.exports
references. The following code wouldn't allow the user to call the function.
module.js
The following won't work.
exports = nano = function database_module(cfg) {return;}
The following will work if module.exports
is set.
module.exports = exports = nano = function database_module(cfg) {return;}
console
var func = require('./module.js'); // the following line will **work** with module.exports func();
Basically node.js doesn't export the object that exports
currently references, but exports the properties of what exports
originally references. Although Node.js does export the object module.exports
references, allowing you to call it like a function.
2nd least important reason
They set both module.exports
and exports
to ensure exports
isn't referencing the prior exported object. By setting both you use exports
as a shorthand and avoid potential bugs later on down the road.
Using exports.prop = true
instead of module.exports.prop = true
saves characters and avoids confusion.
Answer by Sudhir Srinivasan for module.exports vs exports in Node.js
I found this link useful to answer the above question.
http://timnew.github.io/blog/2012/04/20/exports_vs_module_exports_in_node_js/
To add to the other posts The module system in node does
var exports = module.exports
before executing your code. So when you want to exports = foo , you probably want to do module.exports = exports = foo but using exports.foo = foo should be fine
Answer by Chandu for module.exports vs exports in Node.js
Basically the answer lies in what really happens when a module is required via require
statement. Assuming this is the first time the module is being required.
For example:
var x = require('file1.js');
contents of file1.js:
module.exports = '123';
When the above statement is executed, a Module
object is created. Its constructor function is:
function Module(id, parent) { this.id = id; this.exports = {}; this.parent = parent; if (parent && parent.children) { parent.children.push(this); } this.filename = null; this.loaded = false; this.children = []; }
As you see each module object has a property with name exports
. This is what is eventually returned as part of require
.
Next step of require is to wrap the contents of file1.js into an anonymous function like below:
(function (exports, require, module, __filename, __dirname) { //contents from file1.js module.exports = '123; });
And this anonymous function is invoked the following way, module
here refers to the Module
Object created earlier.
(function (exports, require, module, __filename, __dirname) { //contents from file1.js module.exports = '123; }) (module.exports,require, module, "path_to_file1.js","directory of the file1.js");
As we can see inside the function, exports
formal argument refers to module.exports
. In essence it's a convenience provided to the module programmer.
However this convenience need to be exercised with care. In any case if trying to assign a new object to exports ensure we do it this way.
exports = module.exports = {};
If we do it following way wrong way, module.exports
will still be pointing to the object created as part of module instance.
exports = {};
As as result adding anything to the above exports object will have no effect to module.exports object and nothing will be exported or returned as part of require.
Answer by cameron for module.exports vs exports in Node.js
Initially,module.exports=exports
, and the require
function returns the object module.exports
refers to.
if we add property to the object, say exports.a=1
, then module.exports and exports still refer to the same object. So if we call require and assign the module to a variable, then the variable has a property a and it's value is 1;
But if we override one of them, for example, exports=function(){}
, then they are different now: exports refers to a new object and module.exports refer to the original object. And if we require the file, it will not return the new object, since module.exports is not refer to the new object.
For me, i will keep adding new property, or override both of them to a new object. Just override one is not right. And keep in mind that module.exports
is the real boss.
Answer by Lyman Lai for module.exports vs exports in Node.js
I just make some test, it turns out that, inside nodejs's module code, it should something like this:
var module.exports = {}; var exports = module.exports;
so:
1:
exports = function(){}; // this will not work! as it make the exports to some other pointer module.exports = function(){}; // it works! cause finally nodejs make the module.exports to export.
2:
exports.abc = function(){}; // works! exports.efg = function(){}; // works!
3: but, while in this case
module.exports = function(){}; // from now on we have to using module.exports to attach more stuff to exports. module.exports.a = 'value a'; // works exports.b = 'value b'; // the b will nerver be seen cause of the first line of code we have do it before (or later)
Answer by sidias for module.exports vs exports in Node.js
in node js module.js file is use to run the module.load system.every time when node execute a file it wrap your js file content as follow
'(function (exports, require, module, __filename, __dirname) {',+ //your js file content '\n});'
because of this wrapping inside ur js source code you can access exports,require,module,etc.. this approach is used because there is no other way to get functionalities wrote in on js file to another.
then node execute this wrapped function using c++. at that moment exports object that passed into this function will be filled.
you can see inside this function parameters exports and module. actually exports is a public member of module constructor function.
look at following code
copy this code into b.js
console.log("module is "+Object.prototype.toString.call(module)); console.log("object.keys "+Object.keys(module)); console.log(module.exports); console.log(exports === module.exports); console.log("exports is "+Object.prototype.toString.call(exports)); console.log('----------------------------------------------'); var foo = require('a.js'); console.log("object.keys of foo: "+Object.keys(foo)); console.log('name is '+ foo); foo();
copy this code to a.js
exports.name = 'hello'; module.exports.name = 'hi'; module.exports.age = 23; module.exports = function(){console.log('function to module exports')}; //exports = function(){console.log('function to export');}
now run using node
this is the output
module is [object Object] object.keys id,exports,parent,filename,loaded,children,paths {} true
exports is [object Object]
object.keys of foo: name is function (){console.log('function to module exports')} function to module exports
now remove the commented line in a.js and comment the line above that line and remove the last line of b.js and run.
in javascript world you cannot reassign object that passed as parameter but you can change function's public member when object of that function set as a parameter to another function
do remember
use module.exports on and only if you wants to get a function when you use require keyword . in above example we var foo = require(a.js); you can see we can call foo as a function;
this is how node documentation explain it "The exports object is created by the Module system. Sometimes this is not acceptable, many want their module to be an instance of some class. To do this assign the desired export object to module.exports."
Answer by Bob KaKoO for module.exports vs exports in Node.js
"If you want the root of your module's export to be a function (such as a constructor) or if you want to export a complete object in one assignment instead of building it one property at a time, assign it to module.exports instead of exports." - http://nodejs.org/api/modules.html
Answer by Cody for module.exports vs exports in Node.js
I went through some tests and I think this may shed some light on the subject...
app.js
:
var ... , routes = require('./routes') ...; ... console.log('@routes', routes); ...
versions of /routes/index.js
:
exports = function fn(){}; // outputs "@routes {}" exports.fn = function fn(){}; // outputs "@routes { fn: [Function: fn] }" module.exports = function fn(){}; // outputs "@routes function fn(){}" module.exports.fn = function fn(){}; // outputs "@routes { fn: [Function: fn] }"
I even added new files:
./routes/index.js
:
module.exports = require('./not-index.js'); module.exports = require('./user.js');
./routes/not-index.js
:
exports = function fn(){};
./routes/user.js
:
exports = function user(){};
We get the output "@routes {}"
./routes/index.js
:
module.exports.fn = require('./not-index.js'); module.exports.user = require('./user.js');
./routes/not-index.js
:
exports = function fn(){};
./routes/user.js
:
exports = function user(){};
We get the output "@routes { fn: {}, user: {} }"
./routes/index.js
:
module.exports.fn = require('./not-index.js'); module.exports.user = require('./user.js');
./routes/not-index.js
:
exports.fn = function fn(){};
./routes/user.js
:
exports.user = function user(){};
We get the output "@routes { user: [Function: user] }" If we change user.js
to { ThisLoadedLast: [Function: ThisLoadedLast] }
, we get the output "@routes { ThisLoadedLast: [Function: ThisLoadedLast] }".
But if we modify ./routes/index.js
...
./routes/index.js
:
module.exports.fn = require('./not-index.js'); module.exports.ThisLoadedLast = require('./user.js');
./routes/not-index.js
:
exports.fn = function fn(){};
./routes/user.js
:
exports.ThisLoadedLast = function ThisLoadedLast(){};
... we get "@routes { fn: { fn: [Function: fn] }, ThisLoadedLast: { ThisLoadedLast: [Function: ThisLoadedLast] } }"
So I would suggest always use module.exports
in your module definitions.
I don't completely understand what's going on internally with Node, but please comment if you can make more sense of this as I'm sure it helps.
-- Happy coding
Answer by Srle for module.exports vs exports in Node.js
Even question is answered and accepted long ago, just want to share my 2 cents:
You can imagine that at very begining of your file there is something like (just for explanation):
var module = new Module(...); var exports = module.exports;
So whatever you do just keep in mind that module.exports
and NOT exports
will be returned from your module when you requiring that module from somewhere else.
So when you do something like:
exports.a = function() { console.log("a"); } exports.b = function() { console.log("b"); }
You are adding 2 function 'a' and 'b' to the object on which module.exports points too, so typeof returning result will be an object
: { a: [Function], b: [Function] }
Of course this is the same result you will get if you are using module.exports
in this example instead of exports
.
This is the case where you want your module.exports to behave like container of exported values. In the case where you only want to export a constructor function, what you will do? (Remember again that module.exports will be returned when you required something, not export).
module.exports = function Something() { console.log('bla bla'); }
Now typeof returning result is 'function'
and you can required it and immediately invoke like:
var x = require('./file1.js')();
because you overwrite the returning result to be an function.
Why in this case you can't use something like:
exports = function Something() { console.log('bla bla'); }
Because with this exports
reference doesn't 'point' anymore to the object where module.exports
points, so there is not a relationship between exports
and module.exports
anymore. In this case module.exports still points to the empty object {}
which will be returned.
Accepted answer from another topic should also help: Does JavaScript pass by reference?
Answer by superluminary for module.exports vs exports in Node.js
JavaScript passes by reference
It's a subtle difference to do with the way objects are passed by reference in JavaScript.
exports
and module.exports
both point to the same object. exports
is a variable and module.exports
is an attribute of the module object.
Say I write something like this:
exports = {a:1}; module.exports = {b:12};
exports
and module.exports
now point to different objects. Modifying exports no longer modifies module.exports.
When the import function inspects module.exports
it gets {b:12}
Answer by Salar for module.exports vs exports in Node.js
Here is a good description written about node modules in node.js in action book from Manning publication.
What ultimately gets exported in your application is module.exports.
exports is set up simply as a global reference to module.exports , which initially is defined as an empty object that you can add properties to. So exports.myFunc is just shorthand for module.exports.myFunc.
As a result, if exports is set to anything else, it breaks the reference between module.exports and exports . Because module.exports is what really gets exported, exports will no longer work as expected?it doesn?t reference module .exports anymore. If you want to maintain that link, you can make module.exports reference exports again as follows:
module.exports = exports = db;
Answer by onmyway133 for module.exports vs exports in Node.js
This shows how require()
works in its simplest form, excerpted from Eloquent JavaScript
Problem It is not possible for a module to directly export a value other than the exports object, such as a function. For example, a module might want to export only the constructor of the object type it defines. Right now, it cannot do that because require always uses the exports
object it creates as the exported value.
Solution Provide modules with another variable, module
, which is an object that has a property exports
. This property initially points at the empty object created by require but can be overwritten with another value in order to export something else.
function require(name) { if (name in require.cache) return require.cache[name]; var code = new Function("exports, module", readFile(name)); var exports = {}, module = {exports: exports}; code(exports, module); require.cache[name] = module.exports; return module.exports; } require.cache = Object.create(null);
Answer by dustin.schultz for module.exports vs exports in Node.js
exports
and module.exports
are the same unless you reassign exports
within your module.
The easiest way to think about it, is to think that this line is implicitly at the top of every module.
var exports = module.exports = {};
If, within your module, you reassign exports
, then you reassign it within your module and it no longer equals module.exports
. This is why, if you want to export a function, you must do:
module.exports = function() { ... }
If you simply assigned your function() { ... }
to exports
, you would be reassigning exports
to no longer point to module.exports
.
If you don't want to refer to your function by module.exports
every time, you can do:
module.exports = exports = function() { ... }
Notice that module.exports
is the left most argument.
Attaching properties to exports
is not the same since you are not reassigning it. That is why this works
exports.foo = function() { ... }
Answer by serdem420 for module.exports vs exports in Node.js
Here is the result of
console.log("module:"); console.log(module); console.log("exports:"); console.log(exports); console.log("module.exports:"); console.log(module.exports);
Also:
if(module.exports === exports){ console.log("YES"); }else{ console.log("NO"); } //YES
Note: The CommonJS specification only allows the use of the exports variable to expose public members. Therefore, the named exports pattern is the only one that is really compatible with the CommonJS specification. The use of module.exports is an extension provided by Node.js to support a broader range of module definition patterns.
Fatal error: Call to a member function getElementsByTagName() on a non-object in D:\XAMPP INSTALLASTION\xampp\htdocs\endunpratama9i\www-stackoverflow-info-proses.php on line 72
0 comments:
Post a Comment