node icon indicating copy to clipboard operation
node copied to clipboard

importModuleDynamically for vm module is cached

Open takerusilt opened this issue 4 years ago • 3 comments

  • 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.

takerusilt avatar Dec 02 '20 06:12 takerusilt

@nodejs/modules

targos avatar Dec 06 '20 14:12 targos

this is a bug in v8 that they have been very unenthusiastic about fixing.

devsnek avatar Dec 06 '20 15:12 devsnek

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

redyetidev avatar May 05 '24 22:05 redyetidev

The host defined options leak in the compilation cache has already been fixed by V8. Closing.

joyeecheung avatar Jul 11 '24 12:07 joyeecheung