— Javascript, Node — 1 min read
When upgrading to Node 14, I ran into this issue where running the test suite would throw a set of warnings like so:
1(node:79706) Warning: Accessing non-existent property 'cat' of module exports inside circular dependency2(Use `node --trace-warnings ...` to show where the warning was created)3(node:79706) Warning: Accessing non-existent property 'cd' of module exports inside circular dependency4(node:79706) Warning: Accessing non-existent property 'chmod' of module exports inside circular dependency5(node:79706) Warning: Accessing non-existent property 'cp' of module exports inside circular dependency
One way of finding out what packages were throwing these warnings was by running the same command but with the --trace-warnings
option:
1npx cross-env NODE_OPTIONS="--trace-warnings" yarn test
This helped in pinpointing which packages needed to be updated!
Here is a contrived example of two classes depending on each other:
1// a.js2const B = require('./b');3
4class A {5 constructor(name) {6 this.name = name;7 this.b = new B();8 this.b.log(name);9 }10}11
12const a = new A('cat')13
14module.exports = A;15
16// b.js17const A = require('./a');18
19class B {20 constructor() {21 this.a = A;22 console.log(this.a)23 }24
25 log(stuff) {26 console.log(stuff)27 }28}29
30module.exports = B;31
32// package.json33 "scripts": {34 "build": "node a.js"35 },
Now building our files gives us this warning:
1$ yarn build2
3(node:18952) Warning: Accessing non-existent property 'Symbol(nodejs.util.inspect.custom)' of module exports inside circular dependency4(Use `node --trace-warnings ...` to show where the warning was created)
Now using --trace-warnings
we can see where this issue is happening:
1$ npx cross-env NODE_OPTIONS="--trace-warnings" yarn build2
3(node:18978) Warning: Accessing non-existent property 'Symbol(nodejs.util.inspect.custom)' of module exports inside circular dependency4 at emitCircularRequireWarning (node:internal/modules/cjs/loader:698:11)5 at Object.get (node:internal/modules/cjs/loader:712:5)6 at formatValue (node:internal/util/inspect:746:30)7 at inspect (node:internal/util/inspect:330:10)8 at formatWithOptionsInternal (node:internal/util/inspect:1998:40)9 at formatWithOptions (node:internal/util/inspect:1880:10)10 at console.value (node:internal/console/constructor:327:14)11 at console.log (node:internal/console/constructor:363:61)12 at new B (/Users/ygaberman/programs/test/b.js:6:17)13 at new A (/Users/ygaberman/programs/test/a.js:7:18)
The last two lines show us where the dependency is. This is quite useful for chasing down any circular dependencies!
Can we fix it? Yes.