diff --git a/test/es-module/test-esm-loader-resolve-type.mjs b/test/es-module/test-esm-loader-resolve-type.mjs index 482320c664c5d8..49383e3e0ed309 100644 --- a/test/es-module/test-esm-loader-resolve-type.mjs +++ b/test/es-module/test-esm-loader-resolve-type.mjs @@ -1,44 +1,38 @@ -// Flags: --loader ./test/fixtures/es-module-loaders/hook-resolve-type.mjs -import { allowGlobals } from '../common/index.mjs'; +import { spawnPromisified } from '../common/index.mjs'; import * as fixtures from '../common/fixtures.mjs'; -import { strict as assert } from 'assert'; -import * as fs from 'fs'; - -allowGlobals(global.getModuleTypeStats); - -const { importedESM: importedESMBefore, - importedCJS: importedCJSBefore } = await global.getModuleTypeStats(); - -const basePath = - new URL('./node_modules/', import.meta.url); - -const rel = (file) => new URL(file, basePath); -const createDir = (path) => { - if (!fs.existsSync(path)) { - fs.mkdirSync(path); - } -}; +import { match } from 'node:assert'; +import { mkdir, rm, cp } from 'node:fs/promises'; +import { tmpdir } from 'node:os'; +import { execPath } from 'node:process'; +import { fileURLToPath, pathToFileURL } from 'node:url'; +const base = new URL(`test-esm-loader-resolve-type-${(Math.random() * Date.now()).toFixed(0)}`, pathToFileURL(tmpdir())); const moduleName = 'module-counter-by-type'; -const moduleDir = rel(`${moduleName}`); +const moduleURL = new URL(`${base}/node_modules/${moduleName}`); try { - createDir(basePath); - createDir(moduleDir); - fs.cpSync( - fixtures.path('es-modules', moduleName), - moduleDir, + await mkdir(moduleURL, { recursive: true }); + await cp( + fixtures.path('es-modules', 'module-counter-by-type'), + moduleURL, { recursive: true } ); + const { stdout } = await spawnPromisified( + execPath, + [ + '--input-type=module', + '--eval', + `import { getModuleTypeStats } from ${JSON.stringify(fixtures.fileURL('es-module-loaders', 'hook-resolve-type.mjs'))}; + const before = getModuleTypeStats(); + await import('${moduleName}'); + const after = getModuleTypeStats(); + console.log(JSON.stringify({ before, after }));`, + ], + { cwd: fileURLToPath(base) }, + ); - await import(`${moduleName}`); + // Dynamic import in the eval script should increment ESM counter but not CJS counter + match(stdout, /{"before":{"importedESM":0,"importedCJS":0},"after":{"importedESM":1,"importedCJS":0}}/); } finally { - fs.rmSync(basePath, { recursive: true, force: true }); + await rm(base, { recursive: true, force: true }); } - -const { importedESM: importedESMAfter, - importedCJS: importedCJSAfter } = await global.getModuleTypeStats(); - -// Dynamic import above should increment ESM counter but not CJS counter -assert.strictEqual(importedESMBefore + 1, importedESMAfter); -assert.strictEqual(importedCJSBefore, importedCJSAfter); diff --git a/test/fixtures/es-module-loaders/hook-resolve-type-loader.mjs b/test/fixtures/es-module-loaders/hook-resolve-type-loader.mjs new file mode 100644 index 00000000000000..f2dc0aba5ca80e --- /dev/null +++ b/test/fixtures/es-module-loaders/hook-resolve-type-loader.mjs @@ -0,0 +1,18 @@ +/** @type {MessagePort} */ +let port; +export function initialize(data) { + port = data.port; +} + +export async function resolve(specifier, context, next) { + const nextResult = await next(specifier, context); + const { format } = nextResult; + + if (format === 'module' || specifier.endsWith('.mjs')) { + port.postMessage({ type: 'module' }); + } else if (format == null || format === 'commonjs') { + port.postMessage({ type: 'commonjs' }); + } + + return nextResult; +} diff --git a/test/fixtures/es-module-loaders/hook-resolve-type.mjs b/test/fixtures/es-module-loaders/hook-resolve-type.mjs index a4d87938ad843f..6fa7a553b8e83f 100644 --- a/test/fixtures/es-module-loaders/hook-resolve-type.mjs +++ b/test/fixtures/es-module-loaders/hook-resolve-type.mjs @@ -1,44 +1,30 @@ +import * as fixtures from '../../common/fixtures.mjs'; +import { register } from 'node:module'; +import { MessageChannel } from 'node:worker_threads'; + let importedESM = 0; let importedCJS = 0; +export function getModuleTypeStats() { + return { importedESM, importedCJS }; +}; -export function globalPreload({ port }) { - port.on('message', (int32) => { - port.postMessage({ importedESM, importedCJS }); - Atomics.store(int32, 0, 1); - Atomics.notify(int32, 0); - }); - port.unref(); - return ` - const { receiveMessageOnPort } = getBuiltin('worker_threads'); - global.getModuleTypeStats = async function getModuleTypeStats() { - const sab = new SharedArrayBuffer(4); - const int32 = new Int32Array(sab); - port.postMessage(int32); - // Artificial timeout to keep the event loop alive. - // https://bugs.chromium.org/p/v8/issues/detail?id=13238 - // TODO(targos) Remove when V8 issue is resolved. - const timeout = setTimeout(() => { throw new Error('timeout'); }, 1_000); - await Atomics.waitAsync(int32, 0, 0).value; - clearTimeout(timeout); - return receiveMessageOnPort(port).message; - }; - `; -} - -export async function load(url, context, next) { - return next(url); -} +const { port1, port2 } = new MessageChannel(); -export async function resolve(specifier, context, next) { - const nextResult = await next(specifier, context); - const { format } = nextResult; +register(fixtures.fileURL('es-module-loaders/hook-resolve-type-loader.mjs'), { + data: { port: port2 }, + transferList: [port2], +}); - if (format === 'module' || specifier.endsWith('.mjs')) { - importedESM++; - } else if (format == null || format === 'commonjs') { - importedCJS++; +port1.on('message', ({ type }) => { + switch (type) { + case 'module': + importedESM++; + break; + case 'commonjs': + importedCJS++; + break; } +}); - return nextResult; -} - +port1.unref(); +port2.unref();