Search code examples
node.jsmodule.exports

How does exports object reference module.exports in Node.js?


In Node.js, module object contains an exports property, that is an empty object. This object can be used to reference module.exports (exports.a = "A";), unless it is reassigned (module.exports = "one";).

My question is - what makes this exports object reference module.exports?


Solution

  • CommonJS modules are actually pretty simple: you take all the code in a file, and just wrap it in a function. Execute the function, and return the value of module.exports after execution to the caller.

    You can see this function's header in the node.js source code:

    const wrapper = [
      '(function (exports, require, module, __filename, __dirname) { ',
      '\n});'
    ];
    

    The wrapper is applied to the code in the require'd file and then called like this:

      const exports = this.exports;
      const thisValue = exports;
      const module = this;
      if (requireDepth === 0) statCache = new Map();
      if (inspectorWrapper) {
        result = inspectorWrapper(compiledWrapper, thisValue, exports,
                                  require, module, filename, dirname);
      } else {
        result = compiledWrapper.call(thisValue, exports, require, module,
                                      filename, dirname);
      }
    

    As you can see it's pretty straightforward. const exports = this.exports, and then exports is passed as an argument to the wrapper function - thus they initially point to the same value, but if you reassign either then they no longer do.