Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

resolve hook is not run for require #55878

Open
BadIdeaException opened this issue Nov 16, 2024 · 0 comments
Open

resolve hook is not run for require #55878

BadIdeaException opened this issue Nov 16, 2024 · 0 comments
Labels
loaders Issues and PRs related to ES module loaders

Comments

@BadIdeaException
Copy link

BadIdeaException commented Nov 16, 2024

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):

module#resolve

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.

section "enabling":

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.

@RedYetiDev RedYetiDev added the loaders Issues and PRs related to ES module loaders label Nov 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
loaders Issues and PRs related to ES module loaders
Projects
None yet
Development

No branches or pull requests

2 participants