Trace Warnings with Node
— Javascript, Node — 2 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:
(node:79706) Warning: Accessing non-existent property 'cat' of module exports inside circular dependency(Use `node --trace-warnings ...` to show where the warning was created)(node:79706) Warning: Accessing non-existent property 'cd' of module exports inside circular dependency(node:79706) Warning: Accessing non-existent property 'chmod' of module exports inside circular dependency(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:
npx cross-env NODE_OPTIONS="--trace-warnings" yarn test
This helped in pinpointing which packages needed to be updated!
Bonus
Here is a contrived example of two classes depending on each other:
// a.jsconst B = require('./b');
class A { constructor(name) { this.name = name; this.b = new B(); this.b.log(name); }}
const a = new A('cat')
module.exports = A;
// b.jsconst A = require('./a');
class B { constructor() { this.a = A; console.log(this.a) }
log(stuff) { console.log(stuff) }}
module.exports = B;
// package.json "scripts": { "build": "node a.js" },
Now building our files gives us this warning:
$ yarn build
(node:18952) Warning: Accessing non-existent property 'Symbol(nodejs.util.inspect.custom)' of module exports inside circular dependency(Use `node --trace-warnings ...` to show where the warning was created)
Now using --trace-warnings
we can see where this issue is happening:
$ npx cross-env NODE_OPTIONS="--trace-warnings" yarn build
(node:18978) Warning: Accessing non-existent property 'Symbol(nodejs.util.inspect.custom)' of module exports inside circular dependency at emitCircularRequireWarning (node:internal/modules/cjs/loader:698:11) at Object.get (node:internal/modules/cjs/loader:712:5) at formatValue (node:internal/util/inspect:746:30) at inspect (node:internal/util/inspect:330:10) at formatWithOptionsInternal (node:internal/util/inspect:1998:40) at formatWithOptions (node:internal/util/inspect:1880:10) at console.value (node:internal/console/constructor:327:14) at console.log (node:internal/console/constructor:363:61) at new B (/Users/ygaberman/programs/test/b.js:6:17) 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.