Reputation: 83
I'm trying to understand module.exports better. As I understand it, it can be used as a two way communication (you can send and receive data to the module.
However, this is not working as I expected:
File1.js:
var Test = require("./Balances")
Test.push(12)
Balances.js:
var arrays = [10, 11];
module.exports = arrays
File2.js:
var Test = require("./Balances")
setInterval(function(){console.log(Test)},2000)
What I want is to be able to add to the array from File1, and read the output in File2.
File2 reads the initial array just fine, but the value I push never shows in File2.
However, if I add a console.log(Test) in File1, that pushed value does appear there. Upon rerunning File1, I don't however see [12, 12] , only [ 12 ], which means the first push never got written in the Balances array.
Any idea why?
Upvotes: 2
Views: 4181
Reputation: 12637
Technically you can use modules like that, but I'd avoid that. Mutating state like that can lead to a lot of problems, especially if it is done in distributed modules.
And out of a sudden you have some error or unwanted behaviour that seems to come out of nowhere. Because its source is in an completely unrelated part of your app. Have fun, finding/debugging that.
I'd rather use modules as read-only sources for configs and stuff, or export a self-contained API that manages these mutations and everything else that happens in that module.
all you need is a common entry point that loads both modules in the same application.
That's probably ýour misconception. every time you call node ...
you start a seperate application with seperate memory and state. It loads the files you tell it to, executes the code and eventually finishes. Like opening two sites in the browser, one loading File1
, the other one loading File2
.
So, you can create a common entry point like main.js
require("./File1");
require("./File2");
and then start the application at that common entry point node main.js
Or you can run node -i -r "./File1" -r "./File2"
and start typing more JS.
Upvotes: 0
Reputation: 618
It had to have never gotten pushed because you didn't actually require File1.js anywhere. This main.js works exactly as expected with the original File1.js, File2.js, and Balances.js files. (You probably wanted setTimeout, and as mentioned that had no effect anyhow, but it does work.)
require('./File1')
require('./File2')
Yes, modifying passed non-primitives updates the original item. They are not copied. Don't spend the next few years on a redundant construct to rebuild what is already happening.
Upvotes: 0
Reputation: 370
When you import a variable from another javascript module, you get that variable by value, not by reference (you create a copy of the value at the given memory address, you don't simply get a pointer to that same exact variable). Therefore, you have only mutated the Test
variable in File1.js
; to reflect those changes in your console.log
in File2.js
you would have to re-export your mutated variable from File1.js
and import that into File2.js
, and then do the log.
Here is analysis of your code:
File1.js:
// creates copy of the `Balance.js` `arrays` variable
// stores value in new variable `Test`
var Test = require("./Balances") // => [10, 11]
// pushes 12 to the copy
Test.push(12) // => [10, 11, 12]
File2.js:
// creates copy of the `Balance.js` `arrays` variable
// stores value in new variable `Test`
var Test = require("./Balances") // => [10, 11]
// This interval does nothing. The fact is, the mutated
// `arrays` var from `File1.js` does not effect the
// `arrays` var in any other modules scope.
setInterval(function(){console.log(Test)},2000) // => [10, 11]
This is all assuming you have additional code not seen here that is required and executed from an entry point. As Thomas said in the comments, there is no state persisted between running individual scripts.
To accomplish what you're attempting in your post:
Balances.js:
var arrays = [10, 11]
module.exports = arrays
File1.js:
var test = require('./Balances')
test.push(12)
module.exports = test
File2.js:
var test = require('./File1')
function action() {
console.log(test)
}
module.exports = action
main.js (entry point):
var action = require('./File2')
action() // => [10, 11, 12]
run $ node main.js
Hope this helps!
Upvotes: 4