Description
Version
23.0.0
Platform
Linux hooks 6.8.0-47-generic #47~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Wed Oct 2 16:16:55 UTC 2 x86_64 x86_64 x86_64 GNU/Linux
Subsystem
customization hooks
What steps will reproduce the bug?
Set up a module resolution hook that replaces the core fs
import with fake.js
. Then try to import and require fs
, respectively. When importing, fs
is replaced as expected. When requiring, the hook is never run.
For the setup:
register.js:
import { register } from 'node:module';
register('./hook.js', import.meta.url);
hook.js:
import { fileURLToPath } from 'node:url';
import { dirname, join } from 'node:path';
export async function resolve(specifier, context, nextResolve) {
const path = fileURLToPath(import.meta.url);
const dir = dirname(path);
if (/fs/.test(specifier)) specifier = join(dir, 'fake.js');
return nextResolve(specifier, context);
};
fake.js:
export function readFileSync() { return 'foo'; }
Now we're ready for the money part:
index.js
import {readFileSync} from 'fs';
import { fileURLToPath } from 'node:url';
console.log(readFileSync(fileURLToPath(import.meta.url), 'utf8')); // 'foo'
index.cjs:
const readFileSync = require('fs').readFileSync;
console.log(readFileSync(__filename, 'utf8')); // Prints out the source file
NB: type
is set to module
in package.json
.
How often does it reproduce? Is there a required condition?
Can be reliably reproduced every time.
What is the expected behavior? Why is that the expected behavior?
Resolve hook should be run even for require
, and replace fs
with fake.js
. The output should be foo
.
I am basing this expectation off of the documentation (emphasis mine):
The resolve hook chain is responsible for telling Node.js where to find and how to cache a given import statement or expression, or require call.
my-app.js can also be CommonJS. Customization hooks will run for any modules that it references via import (and optionally require).
What do you see instead?
node --import=./register.js index.js
produces foo
, as expected.
node --import=./register.js index.cjs
prints out the source file - bad. Annotating the resolve hook with a console.log
statement shows it is never run.
Additional information
I have asked about this on Stack Overflow but not received any answers.