Skip to content

Commit 736a944

Browse files
authored
fix: node: prefixed build-in modules with include/exclude (#149)
1 parent 79340b8 commit 736a944

File tree

2 files changed

+43
-1
lines changed

2 files changed

+43
-1
lines changed

hook.js

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
const { URL } = require('url')
66
const { inspect } = require('util')
7+
const { builtinModules } = require('module')
78
const specifiers = new Map()
89
const isWin = process.platform === 'win32'
910

@@ -116,6 +117,11 @@ function isBareSpecifier (specifier) {
116117
}
117118
}
118119

120+
/**
121+
* Determines whether the input is a bare specifier, file URL or a regular expression.
122+
*
123+
* - node: prefixed URL strings are considered bare specifiers in this context.
124+
*/
119125
function isBareSpecifierFileUrlOrRegex (input) {
120126
if (input instanceof RegExp) {
121127
return true
@@ -131,13 +137,21 @@ function isBareSpecifierFileUrlOrRegex (input) {
131137
try {
132138
// eslint-disable-next-line no-new
133139
const url = new URL(input)
134-
return url.protocol === 'file:'
140+
// We consider node: URLs bare specifiers in this context
141+
return url.protocol === 'file:' || url.protocol === 'node:'
135142
} catch (err) {
136143
// Anything that fails parsing is a bare specifier
137144
return true
138145
}
139146
}
140147

148+
/**
149+
* Ensure an array only contains bare specifiers, file URLs or regular expressions.
150+
*
151+
* - We consider node: prefixed URL string as bare specifiers in this context.
152+
* - For node built-in modules, we add additional node: prefixed modules to the
153+
* output array.
154+
*/
141155
function ensureArrayWithBareSpecifiersFileUrlsAndRegex (array, type) {
142156
if (!Array.isArray(array)) {
143157
return undefined
@@ -149,6 +163,14 @@ function ensureArrayWithBareSpecifiersFileUrlsAndRegex (array, type) {
149163
throw new Error(`'${type}' option only supports bare specifiers, file URLs or regular expressions. Invalid entries: ${inspect(invalid)}`)
150164
}
151165

166+
// Rather than evaluate whether we have a node: scoped built-in-module for
167+
// every call to resolve, we just add them to include/exclude now.
168+
for (const each of array) {
169+
if (typeof each === 'string' && !each.startsWith('node:') && builtinModules.includes(each)) {
170+
array.push(`node:${each}`)
171+
}
172+
}
173+
152174
return array
153175
}
154176

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { register } from 'module'
2+
import Hook from '../../index.js'
3+
import { strictEqual } from 'assert'
4+
5+
register('../../hook.mjs', import.meta.url, { data: { include: ['node:util', 'os'] } })
6+
7+
const hooked = []
8+
9+
Hook((exports, name) => {
10+
hooked.push(name)
11+
})
12+
13+
await import('util')
14+
await import('node:os')
15+
await import('fs')
16+
await import('path')
17+
18+
strictEqual(hooked.length, 2)
19+
strictEqual(hooked[0], 'util')
20+
strictEqual(hooked[1], 'os')

0 commit comments

Comments
 (0)