I'm beginner in NodeJS(version v21.6.1) and I tried to implement a code in multiple modules to understand side-effect concept in JavaScript but the code not worked, why?
// main.js
import './bootstrap.js';
console.log(` >>>>>>>>>>>>>> ${globalThis.someFunctionDep}`);
// >>>>>>>>>>>>>> undefined
globalThis.someFunctionDep = true;
import './someModule.js';
// bootstrap.js
export default () => {
globalThis.someFunctionDep = false;
console.log("??????????????????");
}
// someModule.js
if (!Object.hasOwn(globalThis, "someFunctionDep") || !globalThis.someFunctionDep) {
throw 'globalThis.someFunctionDep is not set';
}
I desired to automatically exported function in bootstrap.js
module ran and add global variable someFunctionDep
to context and accessible by others modules, but currently on the others this value is not available and is undefined
.
Notice: If you answer is "function on the bootstrap.js file not ran automatically", please read this post .
I desired to automatically exported function in
bootstrap.js
module ran and add global variablesomeFunctionDep
to context and accessible by others modules, but currently on the others this value is not available and is undefined.
The issue is that you never call the function you're exporting from bootstrap.js
. All you've done is export a function. main.js
(or some other module, or bootstrap.js
itself) would have to call that function to see its side-effects, just like any other function.
You've mentioned this answer, saying it conflicts with what I'm saying above, but the difference is that in that answer there's a call to the function (print1
in that case), right there in the module exporting it; notice the print1();
call below the print2
function declaration. Your module doesn't have a call to the function, which is why the code in the function doesn't run.
You need to add a call to your function somewhere. It could be in bootstrap.js
although that would require changing how you export it:
function x() {
globalThis.someFunctionDep = false;
console.log("??????????????????");
}
x();
export default x;
Or it could be in main.js
:
import fn from "./bootstrap.js":
fn();
Note that if it's in main.js
, the call to fn()
won't happen before someModule.js
is loaded; see below for details on that.
I think you're expecting the imports to happen when the import
declarations are reached in the code. That isn't how JavaScript modules work. Instead, module dependencies are determined statically by looking at all of the import
and export
declarations in the interconnected modules, and then modules are loaded and their code executed in the appropriate order for the resulting module graph. Where the import
declarations are in your modules' code relative to the step-by-step code in those modules is irrelevant.
Your main.js
code is functionally equivalent to:
import './bootstrap.js';
import './someModule.js';
console.log(` >>>>>>>>>>>>>> ${globalThis.someFunctionDep}`);
// >>>>>>>>>>>>>> undefined
globalThis.someFunctionDep = true;
...and the top-level code of both bootstrap.js
and someModule.js
will execute before the top-level code of main.js
(because there are no cyclical relationships; it gets more complicated when there are).
Finally: If you want to understand side-effects and module loading, it would probably be simpler just to use console.log
to show when the top-level code in each module ran. For instance:
main.js
:
import "./mod1.js";
import "./mod2.js";
console.log("main");
mod1.js
:
console.log("mod1");
mod2.js
:
console.log("mod2");
With that, you'll see:
mod1
mod2
main