Open
Description
Before it's unflagged
- Figure out default export interop with transpilers, either adding
__esModule
to required ESM on our end (module: add __esModule to require()'d ESM #52166), or transpilers update themselves to check the result returned byrequire()
:conditional exports for module, regardless of whether it's loaded byrequire
orimport
. Something likemodule
which is recognized by Webpack and Rollup would be good (maybe this doesn't need to block unflagging, but should be done before stablization) module: implement the "module-sync" exports condition #54648Move experimental warning to whererequire()
is actually handling a ESM
Before it is promoted to be stable:
- Implement detection module: support ESM detection in the CJS loader #52047Some marker to customize the default exports returned by require(esm) module: support 'module.exports' interop export name in require(esm) #54563Support module customization hooks doc: add synchronous hooks proposal loaders#198
Nice-to-haves:
- Better documentation on how to publish packages in a post-require-esm era/migration guide: https://github.com/nodejs/package-examples
Bug fixes & changes:
- module: disallow CJS <-> ESM edges in a cycle from require(esm) #52264
- module: fix submodules loaded by require() and import() #52487
- module: support ESM detection in the CJS loader #52047
- module: cache synchronous module jobs before linking #52868
- module: add __esModule to require()'d ESM #52166
- module: remove bogus assertion in CJS entrypoint handling with --import #54592
- module: implement the "module-sync" exports condition #54648
- module: check --experimental-require-module separately from detection #55250
- module: include module information in require(esm) warning #55397
- module: trim off internal stack frames for require(esm) warnings #55496
- module: allow ESM that failed to be required to be re-imported #55502
- module: fix error thrown from require(esm) hitting TLA repeatedly #55520
- module: do not warn when require(esm) comes from node_modules #55960
- module: mark evaluation rejection in require(esm) as handled #56122
- module: only emit require(esm) warning under --trace-require-module #56194
Related features that interoperate with require(esm) and need to be considered when being backported together:
v22.x backport (see a summary of regression analysis in #55217 (comment))
- process: add process.features.require_module #55241
- module: use kNodeModulesRE to detect node_modules #55243
- src: implement IsInsideNodeModules() in C++ #55286
- [v22.x] backport unflagging of --experimental-require-module and related fixes/refactorings #55217
v20.x backport: #56927
Metadata
Metadata
Assignees
Labels
Type
Projects
Milestone
Relationships
Development
No branches or pull requests
Activity
GeoffreyBooth commentedon Apr 30, 2024
@nodejs/loaders
jakebailey commentedon May 7, 2024
I just wanted to note it here, but it would be super super awesome if (once stable) this were backported to Node 20/22 or even Node 18 if still in support. I'd love to be able to propose a change to switch TypeScript to ESM (given I have it working without breaking CJS consumers), but the time horizon of Node 22 being the oldest supported version is pretty daunting.
It also seems like there is a hacky way using multiple entrypoints that could allow for TS to grab Node's builtins conditionally without #52599/#52762, though none of that is possible without
require(ESM)
, of course.Even without TypeScript's use case, I think the feature itself is a really important one for the ecosystem. Backporting would really make ESM changeovers a lot less painful.
Andarist commentedon May 7, 2024
IIRC from some Twitter threads - there is a plan to backport this once the feature stabilizes.
joyeecheung commentedon Jul 11, 2024
Regarding the conditional exports, @guybedford suggested to implement just the
module
condition that Rollup and Webpack already recognize. I have a WIP but need to do some testing which involves many combinations of test cases 😵💫 but will also do some npm crawling to see if it can be picked up/is in conflict with any existing popular packages.GeoffreyBooth commentedon Jul 11, 2024
The
module
top level field, or withinexports
?Personally I think
require-module
makes more sense, as it would complement the existingrequire
andimport
keys that Node supports.joyeecheung commentedon Aug 29, 2024
Opened PR for "module" in #54648
If we are starting from scratch, yes, but then the "module" condition has already been adopted by bundlers that support require(esm) in the wild, so it seems better to go along with the existing convention. See https://gist.github.com/sokra/e032a0f17c1721c71cfced6f14516c62
151 remaining items
module: allow ESM that failed to be required to be re-imported
module: trim off internal stack frames for require(esm) warnings
module: fix error thrown from require(esm) hitting TLA repeatedly
module: do not warn when require(esm) comes from node_modules
module: mark evaluation rejection in require(esm) as handled
module: only emit require(esm) warning under --trace-require-module
module: disable require(esm) for policy and network import
styfle commentedon May 18, 2025
Looks like this was backported to 20.x according to the docs which say "Added in: v20.19.0"
https://nodejs.org/docs/latest-v20.x/api/process.html#processfeaturesrequire_module
joyeecheung commentedon Jun 16, 2025
Updated the 20.x backport status. Some pending backports that were/are baking in v22:
kjots commentedon Jul 1, 2025
@joyeecheung Looks like #58515 is now occurring in the latest Node LTS release:
joyeecheung commentedon Jul 1, 2025
The fix just got released in 24 last week. Per the TLS policy it will probably need to wait for the next 22 release (scheduled 2025-07-21) to go out in 22.