Reputation: 4407
Note: this is NOT the same question as node.js require() cache - possible to invalidate?.
I'm writing a script which modifies the main
entry point in the package.json
of a Node.js package and I am having difficulty testing its behaviour.
Here's the example package whose main
entry point I'm trying to modify. It consists of three files.
./node_modules/example/package.json
:
{
"name": "example",
"version": "1.0.0",
"main": "a.js"
}
./node_modules/example/a.js
:
module.exports = { letter: 'A' }
./node_modules/example/b.js
:
module.exports = { letter: 'B' }
As you can see, this package loads a.js
right now, but my script will change it to load b.js
instead.
Here's my script:
const fs = require('fs')
// Here is what we get at first
const first = require('example')
console.log(first) // { letter: 'A' }
// Now rewrite the package.json
const p = JSON.parse(fs.readFileSync('./node_modules/example/package.json', 'utf8'))
console.log(p.main) // 'a.js'
p.main = 'b.js'
fs.writeFileSync('./node_modules/example/package.json', JSON.stringify(p, null, 2))
// Require the module a second time
// We get the same object a second time, because of well-documented caching behaviour
// <https://nodejs.org/api/modules.html#modules_caching>
const second = require('example')
console.log(second === first) // true
console.log(second) // { letter: 'A' }
// Clear the cache, as documented
// <https://nodejs.org/api/modules.html#modules_require_cache>
// <https://stackoverflow.com/questions/9210542/node-js-require-cache-possible-to-invalidate/16060619>
delete require.cache[require.resolve('example')]
// Require the module a third time
// We get a new object... but it's still the old entry point
const third = require('example')
console.log(third === first) // false - a new object
console.log(third) // { letter: 'A' } - STILL THE SAME? should be 'B'
As you can see, after rewriting and saving the new package.json
, and clearing the require
cache, Node.js is still loading the old module!
Digging a little deeper, I've discovered that the value returned from require.resolve('example')
is still ./node_modules/example/a.js
, even though it should be ./node_modules/example/b.js
now. In other words, it looks as if there is some kind of secondary cache for the results of require.resolve
.
My question is this: is there any way for me to access and modify this secondary cache?
Upvotes: 3
Views: 729
Reputation: 4407
Currently it is impossible to do this. The contents of each package.json
loaded by Node.js is cached separately in a variable packageJsonCache
, which is not externally reachable without the addition of a new feature to Node.js' Modules API.
Upvotes: 3