diff --git a/test/es-module/test-esm-loader-hooks.mjs b/test/es-module/test-esm-loader-hooks.mjs index 5c6bf16323f160..76d55fd7815cdc 100644 --- a/test/es-module/test-esm-loader-hooks.mjs +++ b/test/es-module/test-esm-loader-hooks.mjs @@ -67,6 +67,21 @@ describe('Loader hooks', { concurrency: true }, () => { assert.strictEqual(code, 0); assert.strictEqual(signal, null); }); + + it('import.meta.resolve of a never-settling resolve', async () => { + const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [ + '--no-warnings', + '--experimental-import-meta-resolve', + '--experimental-loader', + fixtures.fileURL('es-module-loaders/never-settling-resolve-step/loader.mjs'), + fixtures.path('es-module-loaders/never-settling-resolve-step/import.meta.never-resolve.mjs'), + ]); + + assert.strictEqual(stderr, ''); + assert.match(stdout, /^should be output\r?\n$/); + assert.strictEqual(code, 13); + assert.strictEqual(signal, null); + }); }); describe('should handle never-settling hooks in CJS files', { concurrency: true }, () => { @@ -165,4 +180,19 @@ describe('Loader hooks', { concurrency: true }, () => { assert.strictEqual(code, 1); assert.strictEqual(signal, null); }); + + it('should not leak internals or expose import.meta.resolve', async () => { + const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [ + '--no-warnings', + '--experimental-import-meta-resolve', + '--experimental-loader', + fixtures.fileURL('es-module-loaders/loader-edge-cases.mjs'), + fixtures.path('empty.js'), + ]); + + assert.strictEqual(stderr, ''); + assert.strictEqual(stdout, ''); + assert.strictEqual(code, 0); + assert.strictEqual(signal, null); + }); }); diff --git a/test/fixtures/es-module-loaders/loader-edge-cases.mjs b/test/fixtures/es-module-loaders/loader-edge-cases.mjs new file mode 100644 index 00000000000000..f50df0988194e4 --- /dev/null +++ b/test/fixtures/es-module-loaders/loader-edge-cases.mjs @@ -0,0 +1,15 @@ +import { strictEqual } from "node:assert"; +import { isMainThread, workerData, parentPort } from "node:worker_threads"; + +// TODO(aduh95): switch this to `false` when loader hooks are run on a separate thread. +strictEqual(isMainThread, true); + +// We want to make sure that internals are not leaked on the public module: +strictEqual(workerData, null); +strictEqual(parentPort, null); + +// TODO(aduh95): switch to `"undefined"` when loader hooks are run on a separate thread. +// We don't want `import.meta.resolve` being available from loaders +// as the sync implementation is not compatible with calling async +// functions on the same thread. +strictEqual(typeof import.meta.resolve, 'function'); diff --git a/test/fixtures/es-module-loaders/never-settling-resolve-step/import.meta.never-resolve.mjs b/test/fixtures/es-module-loaders/never-settling-resolve-step/import.meta.never-resolve.mjs new file mode 100644 index 00000000000000..51205a9475889c --- /dev/null +++ b/test/fixtures/es-module-loaders/never-settling-resolve-step/import.meta.never-resolve.mjs @@ -0,0 +1,5 @@ +console.log('should be output'); + +await import.meta.resolve('never-settle-resolve'); + +console.log('should not be output');