node
node copied to clipboard
importModuleDynamically for vm module is cached
- Version: v14.15.1, v15.3.0
- Platform: Windows 10 Pro 64-bit / Mac Darwin Kernel Version 19.6.0: Thu Oct 29 22:56:45 PDT 2020; root:xnu-6153.141.2.2~1/RELEASE_X86_64 x86_64
- Subsystem: vm
What steps will reproduce the bug?
const vm = require('vm');
var counter = 0;
async function link() {
var thisCounter = ++counter;
var module = new vm.SourceTextModule(`
const foo = (await import('foo')).default;
console.log('import.meta.counter', import.meta.counter);
console.log('foo.counter', foo.counter);
`, {
identifier: '',
importModuleDynamically: async () => {
console.log('importModuleDynamically', thisCounter);
const module = new vm.SyntheticModule(['default'], function() {
this.setExport('default', { counter: thisCounter });
});
await module.link(()=>{});
await module.evaluate();
return module;
},
initializeImportMeta: (meta) => {
meta.counter = thisCounter
}
});
await module.link(() => {});
await module.evaluate();
return module;
}
link();
link();
How often does it reproduce? Is there a required condition?
Always.
What is the expected behavior?
importModuleDynamically 1
importModuleDynamically 2
import.meta.counter 1
foo.counter 1
import.meta.counter 2
foo.counter 2
What do you see instead?
importModuleDynamically 1
importModuleDynamically 1
import.meta.counter 1
foo.counter 1
import.meta.counter 2
foo.counter 1
Additional information
vm.SourceTextModule
is caching the importModuleDynamically
callback as long as the source code is the same, where as initializeImportMeta
does not.
If how importModuleDynamically
does its work depends on an external state, often in test suite, it will load modules inconsistently to those state and cause discrepancies as viewed inside the VM modules.
@nodejs/modules
this is a bug in v8 that they have been very unenthusiastic about fixing.
In Node.js v22 this is no longer the case AFAICT:
importModuleDynamically 1
importModuleDynamically 2
import.meta.counter 1
foo.counter 1
import.meta.counter 2
foo.counter 2
The host defined options leak in the compilation cache has already been fixed by V8. Closing.