module.exports vs exports in Node.js

前端 未结 23 1182
自闭症患者
自闭症患者 2020-11-22 06:11

I\'ve found the following contract in a Node.js module:

module.exports = exports = nano = function database_module(cfg) {...}

I wonder what

相关标签:
23条回答
  • 2020-11-22 06:56

    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)
    
    0 讨论(0)
  • 2020-11-22 06:57

    From the docs

    The exports variable is available within a module's file-level scope, and is assigned the value of module.exports before the module is evaluated.

    It allows a shortcut, so that module.exports.f = ... can be written more succinctly as exports.f = .... However, be aware that like any variable, if a new value is assigned to exports, it is no longer bound to module.exports:

    It is just a variable pointing to module.exports.

    0 讨论(0)
  • 2020-11-22 06:57

    module.exports and exports both point to the same object before the module is evaluated.

    Any property you add to the module.exports object will be available when your module is used in another module using require statement. exports is a shortcut made available for the same thing. For instance:

    module.exports.add = (a, b) => a+b
    

    is equivalent to writing:

    exports.add = (a, b) => a+b
    

    So it is okay as long as you do not assign a new value to exports variable. When you do something like this:

    exports = (a, b) => a+b 
    

    as you are assigning a new value to exports it no longer has reference to the exported object and thus will remain local to your module.

    If you are planning to assign a new value to module.exports rather than adding new properties to the initial object made available, you should probably consider doing as given below:

    module.exports = exports = (a, b) => a+b
    

    Node.js website has a very good explanation of this.

    0 讨论(0)
  • 2020-11-22 06:57

    Each file you create is a module. module is an object. It has property called exports : {} which is empty object by default.

    you can create functions/middlewares and add to this empty exports object such as exports.findById() => { ... } then require anywhere in your app and use...

    controllers/user.js

    exports.findById = () => {
        //  do something
    }
    

    require in routes.js to use:

    const {findyId} = './controllers/user'
    
    0 讨论(0)
  • 2020-11-22 07:02

    Setting module.exports allows the database_module function to be called like a function when required. 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.

    0 讨论(0)
  • 2020-11-22 07:02

    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.

    0 讨论(0)
提交回复
热议问题