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
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
loadhook, as documented, must return aformatthat is one of the supported formats. However, the CoffeeScript example further down the page shows aloadhook that returnsundefinedif the controllingpackage.jsonhas notypefield. So, is returningundefinedsupported or not? If it is, what is the behavior?Based on the source code, the default synchronous
load(the one invoked by callingnextLoadof the last user synchronousloadhook) can acceptcontext.sourcein the args. But that is not documented. Is it simply a case of missing documentation? Or is it intentional andcontext.sourceshould not be relied upon?The docs for the synchronous
nextLoadstates that "[i]n the defaultnextLoad, if the module pointed to byurldoes not have explicit module type information,context.formatis 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
loadhook or to pass tonextLoad). But how should we do that? The defaultloadcalls 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-loaderflag says it is "discouraged" and suggests using "--importwithregister()" instead. Butmodule.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
loadhook 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