javascriptnode.jsnode-modulescommonjs

Exposed and private/local members in CommonJS modules


I was testing this framework and got these issues, idk why they happen and couldn't find the answer neither in Node.js docs nor in global search.

init.js

const { f1, v1, v2, f2 } = require('./1.js')

f2()

1.js

module.exports = {
    
    f1: function (v1) { f1(v1) },
    
    v1: 1,
    v2: this.v1 + 1,
    
    f2: function () { f1(this.v2) },
    // * error: outputs NaN .
    
    // f2: function () { this.f1(this.v2) },
    // * error: when called from importing script, crashes with `TypeError: this.f1 is not a function` .
    //  
    //  This function works if `<<name for Object>> = require('<<path>>')` syntax is used .
    
}

function f1 (v1) {
    console.log(v1)
}

Specific questions are:


Solution

  • If you want to preserve the syntax of defining everything inside of module.exports object, you can refer to it in other functions' bodies either through this or through module.exports:

    module.exports = {
      f1: function () {
        // …
      },
    
      f2: function () {
        this.f1()
      },
    
      f3: function () {
        module.exports.f1()
      },
    }
    

    You can't refer to the object by module.exports for variables (non-function properties). This is because while the property value is being calculated, module.exports does not exist yet.

    You also can't refer to it by this, mainly for the same reasons: this refers to a different thing, not the object.


    All of this trouble can be easily avoided (with added benefits, like making the value read-only, more fine-grained visibility control – and many more) if you define things separately from exporting them:

    const v1 = 1
    
    let v2 = v1 + 1
    
    function f1(arg) {
      console.log(arg)
    }
    
    function f2() {
      f1(v2)
    }
    
    module.exports = { v1, v2, f1, f2 }