Skip to content

Commit 976d032

Browse files
authored
feat: Optionally hook internal paths like require-in-the-middle (#194)
1 parent 38f815b commit 976d032

File tree

5 files changed

+52
-2
lines changed

5 files changed

+52
-2
lines changed

README.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,23 @@ fs.readFileSync('file.txt')
109109
node --import=./instrument.mjs ./my-app.mjs
110110
```
111111
112+
### Experimental `experimentalPatchInternals` option
113+
114+
It was found that `import-in-the-middle` didn't match the hooking behavior of `require-in-the-middle` in some cases:
115+
https://github.com/nodejs/import-in-the-middle/issues/185
116+
117+
The `experimentalPatchInternals` option forces the loader to match the behavior of `require-in-the-middle` in these cases.
118+
119+
This option is experimental and may be removed or made the default in the future.
120+
121+
```js
122+
import { register } from 'module'
123+
124+
register('import-in-the-middle/hook.mjs', import.meta.url, {
125+
data: { experimentalPatchInternals: true }
126+
})
127+
```
128+
112129
## Limitations
113130
114131
* You cannot add new exports to a module. You can only modify existing ones.

hook.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ const { inspect } = require('util')
77
const { builtinModules } = require('module')
88
const specifiers = new Map()
99
const isWin = process.platform === 'win32'
10+
let experimentalPatchInternals = false
1011

1112
// FIXME: Typescript extensions are added temporarily until we find a better
1213
// way of supporting arbitrary extensions
@@ -292,6 +293,10 @@ function createHook (meta) {
292293
global.__import_in_the_middle_initialized__ = true
293294

294295
if (data) {
296+
if (data.experimentalPatchInternals) {
297+
experimentalPatchInternals = true
298+
}
299+
295300
includeModules = ensureArrayWithBareSpecifiersFileUrlsAndRegex(data.include, 'include')
296301
excludeModules = ensureArrayWithBareSpecifiersFileUrlsAndRegex(data.exclude, 'exclude')
297302

@@ -410,6 +415,7 @@ function createHook (meta) {
410415
source: `
411416
import { register } from '${iitmURL}'
412417
import * as namespace from ${JSON.stringify(realUrl)}
418+
${experimentalPatchInternals ? `import { setExperimentalPatchInternals } from '${iitmURL}'\nsetExperimentalPatchInternals(true)` : ''}
413419
414420
// Mimic a Module object (https://tc39.es/ecma262/#sec-module-namespace-objects).
415421
const _ = Object.create(null, { [Symbol.toStringTag]: { value: 'Module' } })

index.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ const { MessageChannel } = require('worker_threads')
1010
const {
1111
importHooks,
1212
specifiers,
13-
toHook
13+
toHook,
14+
getExperimentalPatchInternals
1415
} = require('./lib/register')
1516

1617
function addHook (hook) {
@@ -144,7 +145,7 @@ function Hook (modules, options, hookFn) {
144145
if (internals) {
145146
name = name + path.sep + path.relative(baseDir, fileURLToPath(filename))
146147
} else {
147-
if (!baseDir.endsWith(specifiers.get(filename))) continue
148+
if (!getExperimentalPatchInternals() && !baseDir.endsWith(specifiers.get(filename))) continue
148149
}
149150
}
150151
callHookFn(hookFn, namespace, name, baseDir)

lib/register.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,19 @@ function register (name, namespace, set, get, specifier) {
4343
toHook.push([name, proxy])
4444
}
4545

46+
let experimentalPatchInternals = false
47+
48+
function getExperimentalPatchInternals () {
49+
return experimentalPatchInternals
50+
}
51+
52+
function setExperimentalPatchInternals (value) {
53+
experimentalPatchInternals = value
54+
}
55+
4656
exports.register = register
4757
exports.importHooks = importHooks
4858
exports.specifiers = specifiers
4959
exports.toHook = toHook
60+
exports.getExperimentalPatchInternals = getExperimentalPatchInternals
61+
exports.setExperimentalPatchInternals = setExperimentalPatchInternals
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
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: { experimentalPatchInternals: true } })
6+
7+
Hook(['c8'], (exports, name) => {
8+
strictEqual(name, 'c8')
9+
exports.Report = () => 42
10+
})
11+
12+
const { Report } = await import('c8/index.js')
13+
14+
strictEqual(Report({}), 42)

0 commit comments

Comments
 (0)