-
-
Notifications
You must be signed in to change notification settings - Fork 33.7k
Closed
Labels
loadersIssues and PRs related to ES module loadersIssues and PRs related to ES module loaders
Description
This was an idea discussed in the loaders group a few times in the past as well as in the last collaboration summit. Opening an issue to track it properly.
This is related to #55782 and will allow us to
- Eliminate the races in ESM cache handling when
require(esm)needs the linking to be synchronous butimport esmmay populate an asynchronous linking job in the cache. There were multiple band-aids applied to work around this, like esm: link modules synchronously when no async loader hooks are used #59519 and module: handle cached linked async jobs in require(esm) #57187, but to fully eliminate the races, this would be necessary to finish Tracking Issue: Syncify the ESM Loader #55782 - Go back to using the authentic
require()in imported CJS instead of re-inventing a separaterequire()and eliminate its quirks, which currently includes- The re-invented
requirelacks a lot of properties likerequire.cache, which is a documented caveat https://nodejs.org/api/module.html#caveat-in-the-asynchronous-load-hook - this means a lot of code may not be able to load when the async customization hooks are registered, as they directly rely on these properties. - The source code for CJS ended up being loaded twice
node/lib/internal/modules/esm/load.js
Lines 97 to 99 in 0fd1ecd
// For backward compatibility reasons, we need to discard the source in // order for the CJS loader to re-fetch it. source = null; - As a side-effect of the previous quirk, when the module format is CJS, the user hook can't assume the
sourceis available and need to cope withsourcebeingnull, usually by reading directly from the file system (not necessarily correct), like what's being done in import-in-the-middle, see ERR_INVALID_RETURN_PROPERTY_VALUE when using module.register and module.registerHooks #57327 (comment) - Also as a side-effect, if they don't override the nullish value by supplementing source code that they obtain through other means, the
requirein imported CommonJS won't trigger the hooks. - The
resolvehook gets"import"in its conditions array forrequire(), instead of"require"(because it's using ESM resolution). This can lead to wrong modules being loaded when loading packages that split the conditional exports. - The
resolvehook gets the full URL, not the specifier passed torequire() - Invoking the sync hooks twice for CJS, one from the re-invented require, one from the
Module._loadinvocation in the evaluation step.
- The re-invented
Refs: #57327
Refs: #55808
Refs: #52697
Refs: #56241
Refs: #55782
cc @nodejs/loaders
jsumners-nr, timokoessler, mcollina, legendecas, GeoffreyParrier and 1 more
Metadata
Metadata
Assignees
Labels
loadersIssues and PRs related to ES module loadersIssues and PRs related to ES module loaders