Skip to content

Seeking clarification about docs on implementing customization hooks #5150

@clemyan

Description

@clemyan

Node.js Version

v26.1.0

NPM Version

N/A

Operating System

N/A

Subsystem

Other

Description

In response to https://github.com/nodejs/node/pull/62835/changes#diff-bdab80c290d22162f748d1a80a5a2a5211460e5ab3fca7a42af0e8ca128e316dR37-R40, I am trying to reduce Yarn's reliance on monkey-patching for customizing Node's resolution pipeline and onto more formal APIs, specifically module.registerHooks(). Given this, I'd like to avoid undocumented behavior as much as possible. However, while reading the docs there are a few things about customization hooks that I'd like some clarification on.

For context, one of our primary use cases for customization hooks is to create a virtual filesystem layer. Ideally, we would not need to do much more than call our own virtual filesystem APIs to read the contents of file(s).

  • The synchronous load hook, as documented, must return a format that is one of the supported formats. However, the CoffeeScript example further down the page shows a load hook that returns undefined if the controlling package.json has no type field. So, is returning undefined supported or not? If it is, what is the behavior?

  • Based on the source code, the default synchronous load (the one invoked by calling nextLoad of the last user synchronous load hook) can accept context.source in the args. But that is not documented. Is it simply a case of missing documentation? Or is it intentional and context.source should not be relied upon?

  • The docs for the synchronous nextLoad states that "[i]n the default nextLoad, if the module pointed to by url does not have explicit module type information, context.format is mandatory"

    • What does "have explicit module type information" mean? Specifically for file: URL, does that mean having an extension? Or something else?

    • Does "mandatory" here means it must be non-null non-undefined? Must it be one of the accepted module formats? Or just the existence of the field is enough?

  • Depending on the answers to the above, there maybe situations where we do need to determine the format of a module ourselves (either to return from our load hook or to pass to nextLoad). But how should we do that? The default load calls multiple C++ bindings to determine a module's format, including one that calls directly into V8's JavaScript compiler. It would be untenable to expect hook writers to recreate this logic in userland, let alone to keep the implementation synchronized with whatever changes made to Node's logic in the future.

  • Extra question: The docs on the --experimental-loader flag says it is "discouraged" and suggests using "--import with register()" instead. But module.register() is deprecated. Does that mean async customization hooks as a whole are deprecated? Its stability is currently stated as "1.1 - Active Development".

All in all, if I already have an overlay virtual file system API, what's the best way to write a load hook to hook it into Node's pipeline? I am currently hard blocked on having to determine the format of a module the same way Node would.

Minimal Reproduction

No response

Output

No response

Before You Submit

  • I have looked for issues that already exist before submitting this
  • My issue follows the guidelines in the README file, and follows the 'How to ask a good question' guide at https://stackoverflow.com/help/how-to-ask

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions