I have three javascript files
moduleA.js
, moduleB.js
, and index.js
moduleA.js
const {b1} = require('./moduleB');
const a1 = ()=>{
console.log('a1 called')
};
const a2 = ()=>{
console.log('a2 called');
b1()
};
module.exports = {a1, a2};
moduleB.js
const {a1} = require('./moduleA');
const b1 = () => {
console.log('b1 called');
a1();
};
const b2 = () => {
console.log('b2 called');
};
module.exports = {b1, b2};
index.js
const {a2} = require('./moduleA');
a2();
How come invoking a2()
throws an error at runtime because a2
is undefined
in node? I've not seen this type of error in another language such as Java.
Is there a solution to this apart from putting a2
in another file such as moduleC.js
and call moduleC.a2()
?
The current output is:
TypeError: a1 is not a function
at b1 (... /moduleB.js:5:5)
at a2 (... /moduleA.js:7:5)
Expected output is
// a2 called
// b1 called
// a1 called
Additional information
Based on the accepted answer provided by Felix and my understanding of the Modules chapter in Matt Frisbie's Professional JavaScript for Web Developers. I drew this graph to assist my understanding of the module loading process in CommonJS. I hope whoever stumbles upon this question in the future will find it helpful as much as I did.
As mentioned in the comments, the error is that a1
is undefined
, not a2
. The reason for that is that you have a circular dependency between module A and module B.
At the time module B imports a1
from module A, module A's exports
object is still empty, i.e. a1
doesn't exist yet.
To fix this you need to do two things:
a1
until it's needed (which is after all modules are evaluated).const a = require('./moduleA');
// ^^^
const b1 = () => {
console.log('b1 called');
a.a1();
// ^^
};
const b2 = () => {
console.log('b2 called');
};
module.exports = {b1, b2};
const {b1} = require('./moduleB');
exports.a1 = ()=>{
console.log('a1 called')
};
exports.a2 = ()=>{
console.log('a2 called');
b1()
};
Or of course refactor your code so that it doesn't use circular dependencies.