From af6ce2cf02d40ece787701ddf3c6ba89499ca518 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20K=C3=B6ssler?= Date: Thu, 26 Jun 2025 18:59:25 +0200 Subject: [PATCH 1/3] fix: Incompatible with module.registerHooks --- hook.js | 13 ++++++++++++- test/register/v24-register-hooks.mjs | 23 +++++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 test/register/v24-register-hooks.mjs diff --git a/hook.js b/hook.js index 398108c..d9cfe23 100644 --- a/hook.js +++ b/hook.js @@ -8,6 +8,7 @@ const { builtinModules } = require('module') const specifiers = new Map() const isWin = process.platform === 'win32' let experimentalPatchInternals = false +const { readFileSync } = require('fs') // FIXME: Typescript extensions are added temporarily until we find a better // way of supporting arbitrary extensions @@ -466,7 +467,17 @@ register(${JSON.stringify(realUrl)}, _, set, get, ${JSON.stringify(specifiers.ge } } - return parentLoad(url, context, parentLoad) + const parentResult = await parentLoad(url, context, parentLoad) + + // Prevent returning a nullish value for the source if a CJS module is loaded. + // The reason for this is that Node.js will otherwise crash if the synchronous + // module customization hooks are used: https://github.com/nodejs/node/issues/57327 + // The Node.js documentation also mentions that returning nullish values will no longer be supported in future. + if (parentResult.format === 'commonjs' && (parentResult.source === null || parentResult.source === undefined)) { + parentResult.source = readFileSync(fileURLToPath(url), 'utf8') + } + + return parentResult } if (NODE_MAJOR >= 17 || (NODE_MAJOR === 16 && NODE_MINOR >= 12)) { diff --git a/test/register/v24-register-hooks.mjs b/test/register/v24-register-hooks.mjs new file mode 100644 index 0000000..457bd06 --- /dev/null +++ b/test/register/v24-register-hooks.mjs @@ -0,0 +1,23 @@ +import { register, registerHooks } from 'module' +import Hook from '../../index.js' +import { strictEqual } from 'assert' + +register('../../hook.mjs', import.meta.url) + +registerHooks({ + load: (url, context, defaultLoad) => { + return defaultLoad(url, context) + } +}) + +let bar + +Hook((exports, name) => { + if (name.match(/circular-b.mjs/)) { + bar = exports.bar + } +}) + +await import('../fixtures/circular-b.mjs') + +strictEqual(bar, 2) From 50a084e72bb5a2a649e8d4c5890ea2fe2b79edf0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20K=C3=B6ssler?= Date: Thu, 26 Jun 2025 19:04:44 +0200 Subject: [PATCH 2/3] chore: Move require call --- hook.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hook.js b/hook.js index d9cfe23..cb31d85 100644 --- a/hook.js +++ b/hook.js @@ -5,10 +5,10 @@ const { URL, fileURLToPath } = require('url') const { inspect } = require('util') const { builtinModules } = require('module') +const { readFileSync } = require('fs') const specifiers = new Map() const isWin = process.platform === 'win32' let experimentalPatchInternals = false -const { readFileSync } = require('fs') // FIXME: Typescript extensions are added temporarily until we find a better // way of supporting arbitrary extensions From f69fae830c506d5b55a07e6e0eb46056766c563a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20K=C3=B6ssler?= Date: Thu, 26 Jun 2025 19:33:12 +0200 Subject: [PATCH 3/3] chore: Simplify condition Co-authored-by: James Sumners --- hook.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hook.js b/hook.js index cb31d85..5e3a63a 100644 --- a/hook.js +++ b/hook.js @@ -473,7 +473,7 @@ register(${JSON.stringify(realUrl)}, _, set, get, ${JSON.stringify(specifiers.ge // The reason for this is that Node.js will otherwise crash if the synchronous // module customization hooks are used: https://github.com/nodejs/node/issues/57327 // The Node.js documentation also mentions that returning nullish values will no longer be supported in future. - if (parentResult.format === 'commonjs' && (parentResult.source === null || parentResult.source === undefined)) { + if (parentResult.format === 'commonjs' && !parentResult.source) { parentResult.source = readFileSync(fileURLToPath(url), 'utf8') }