2

I have a file foo.js like so

var foo = function() {
    console.log(x + 'foo'); // I want my module that require/import to pass into this file.
};

exports.foo = foo;

I then have another file main.js, which I want to pass a variable to foo.js from here. It is possible?

var x = 'Hi, '; // I want to pass this to the module foo.js. Is it possible?
var foo = require('./foo');

foo.foo(); // I want to see "Hi, foo"

Any pointers will be much appreciated!

2
  • 1
    tutorialsteacher.com/nodejs/nodejs-module-exports This might help you but are do you want to pass a method to another file? Commented Jun 30, 2017 at 23:51
  • Thank you all for the comments! Commented Jul 5, 2017 at 16:07

3 Answers 3

2

You can do something like this

// foo.js
module.exports = {
    foo: function (x) {
        console.log(x + 'foo');
    }
}

// main.js
var foo = require('./foo');
var x = 'Hi';
foo.foo(x);
Sign up to request clarification or add additional context in comments.

1 Comment

It would be nice if you'd point out why the approach of the OP can not work and that there's technically no difference in your approach and the OP's approach plus argument.
1

Understanding NodeJS scope and modules

NodeJS does not provide a global object which implicitly stores variables like window in the browser. In the browser the var x = "Hi"; whould implicitly bind x to window which another function may access.

These objects are available in all modules. Some of these objects aren't actually in the global scope but in the module scope - this will be noted.

The NodeJS documentation says. It further says on the global global object:

In browsers, the top-level scope is the global scope. This means that within the browser var something will define a new global variable. In Node.js this is different. The top-level scope is not the global scope; var something inside a Node.js module will be local to that module.

The NodeJS documentation on modules:

The module wrapper

Before a module's code is executed, Node.js will wrap it with a function wrapper that looks like the following: (function(exports, require, module, __filename, __dirname) { // Module code actually lives in here });

By doing this, Node.js achieves a few things:

  • It keeps top-level variables (defined with var, const or let) scoped to the module rather than the global object.
  • It helps to provide some global-looking variables that are actually specific to the module, such as:
    • The module and exports objects that the implementor can use to export values from the module.
    • The convenience variables __filename and __dirname, containing the module's absolute filename and directory path.

This is why you assign exports a value.

Solutions

Module factory

You should return a wrapper function that accepts a parameter providing it in any

foo.js:

// Export a function that establishes a new scope providing "x"
module.exports = function(x) {
    return {
        foo: function() {
            console.log(x + 'foo'); // I want my module that require/import to pass into this file.
        };
    };
};

main.js:

var x = "Hi",
    // call that factory function passing "x"
    foo = require("./foo")(x).foo;
foo();

Note it uses module.exports since exports = ... alone would only replace the reference in the function parameter that NodeJS wraps around your module code (see the links above) whereas module.exports = ... replace the property of the exported module.

See the NodeJS docs on the difference:

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:

[...]

Assign x to global

This is only for completeness, don't do this.

  • It will make it harder to understand where which references come from.
  • You may accidentially overwrite other globals with the same name defined by other modules.

main.js:

var x = "Hi",
    foo = require("./foo");
global.x = x;
foo();

Now x is defined on the global object and therefore "magically" available in any module.

1 Comment

Besides override and managing issues, is there any more substantial problem I need to be aware of while using the "global" approach? I am down to a path that this is the only solution works in my situation, but I wanna make sure I know all there is in terms of downfalls. Thanks.
0

Why not just have the foo method accept the variable so that you pass x into foo.foo() like foo.foo(x)?

2 Comments

Please don't answer question with counter questions transporting relevant information. Better point out what's the mistake and why Node works the way it works. Thanks.
I was asking whether the OP had a specific reason for not passing the variable to the function, while also providing the example. I did this to prevent posting a question in the comment and then rewording and reposting the same thing in the answer after getting clarification.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.