From d4e106f4bd4f02ad33ddd54cec9341783740aad0 Mon Sep 17 00:00:00 2001 From: Trent Mick Date: Mon, 26 Jan 2026 12:22:23 -0800 Subject: [PATCH 1/2] fix: properly hook builtin modules that require the 'node:' prefix --- index.js | 13 ++++++++++--- test/hook/v18.15-node-prefixed-only.mjs | 12 ++++++++++++ 2 files changed, 22 insertions(+), 3 deletions(-) create mode 100644 test/hook/v18.15-node-prefixed-only.mjs diff --git a/index.js b/index.js index 38a7d0d..a9e0915 100644 --- a/index.js +++ b/index.js @@ -6,6 +6,7 @@ const path = require('path') const parse = require('module-details-from-path') const { fileURLToPath } = require('url') const { MessageChannel } = require('worker_threads') +const { isBuiltin } = require('module') const { importHooks, @@ -124,11 +125,17 @@ function Hook (modules, options, hookFn) { this._iitmHook = (name, namespace, specifier) => { const filename = name - const isBuiltin = name.startsWith('node:') + const isNodeUrl = name.startsWith('node:') let baseDir - if (isBuiltin) { - name = name.replace(/^node:/, '') + if (isNodeUrl) { + // Normalize builtin module name to *not* have 'node:' prefix, unless + // required, as it is for 'node:test' and some others. `module.isBuiltin` + // is available in all Node.js versions that have node:-only modules. + const unprefixed = name.slice(5) + if (typeof isBuiltin !== 'function' || isBuiltin(unprefixed)) { + name = unprefixed + } } else { if (name.startsWith('file://')) { const stackTraceLimit = Error.stackTraceLimit diff --git a/test/hook/v18.15-node-prefixed-only.mjs b/test/hook/v18.15-node-prefixed-only.mjs new file mode 100644 index 0000000..e501d1e --- /dev/null +++ b/test/hook/v18.15-node-prefixed-only.mjs @@ -0,0 +1,12 @@ +// Test that a builtin module that must use 'node:' prefix works. +import { strictEqual } from 'assert' +import Hook from '../../index.js' + +Hook(['node:test'], (exports, name) => { + if (name === 'node:test') { + exports.skip = 'iitm was here' + } +}) + +const { skip } = await import('node:test') +strictEqual(skip, 'iitm was here') From d5eb78966009392fef09d6a068b6dd55306cdb5c Mon Sep 17 00:00:00 2001 From: Trent Mick Date: Mon, 26 Jan 2026 16:22:55 -0800 Subject: [PATCH 2/2] provide fallback for isBuiltin to avoid typeof check everytime --- index.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/index.js b/index.js index a9e0915..0725304 100644 --- a/index.js +++ b/index.js @@ -6,7 +6,11 @@ const path = require('path') const parse = require('module-details-from-path') const { fileURLToPath } = require('url') const { MessageChannel } = require('worker_threads') -const { isBuiltin } = require('module') + +let { isBuiltin } = require('module') +if (!isBuiltin) { + isBuiltin = () => true +} const { importHooks, @@ -133,7 +137,7 @@ function Hook (modules, options, hookFn) { // required, as it is for 'node:test' and some others. `module.isBuiltin` // is available in all Node.js versions that have node:-only modules. const unprefixed = name.slice(5) - if (typeof isBuiltin !== 'function' || isBuiltin(unprefixed)) { + if (isBuiltin(unprefixed)) { name = unprefixed } } else {