GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — esm: bypass CommonJS loader under `--default-type=module` by GeoffreyBooth · Pull Request #49986 · nodejs/node

Conversation

@GeoffreyBooth

@GeoffreyBooth GeoffreyBooth commented Oct 1, 2023 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member

This PR implements the part of #49432 where we avoid using the CommonJS loader for ESM entry points in the new --default-type=module mode. This effectively completes some TODOs in the code that note that particular code paths should be deprecated.

The only user-observable effects of this are that, under --experimental-default-type=module:

  • Extension searching is no longer provided for the main entry point. Users need to type node entry.js, not node entry.
  • Libraries that were monkey-patching the CommonJS loader via code loaded by --require will no longer achieve anything. They weren’t achieving much before, as monkey-patching the CommonJS loader only affects CommonJS and not ES modules, so it’s not like the previous behavior was really working very well (if at all) for applications with an ESM entry point.

This inches us closer to actually deprecating the CommonJS loader and having the ESM loader handle all modules, which is a long term goal that will aid in maintainability and future functionality for the modules subsystem.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

JakobJingleheimer reacted with hooray emoji
All reactions
  • 🎉 1 reaction
@GeoffreyBooth GeoffreyBooth added module Issues and PRs related to the module subsystem. cli Issues and PRs related to the Node.js command-line interface. esm Issues and PRs related to the ECMAScript Modules implementation. labels Oct 1, 2023
@GeoffreyBooth
GeoffreyBooth requested a review from aduh95 October 1, 2023 04:13
@nodejs-github-bot

nodejs-github-bot commented Oct 1, 2023

Copy link
Copy Markdown
Collaborator

Review requested:

  • @nodejs/loaders
All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@nodejs-github-bot nodejs-github-bot added needs-ci PRs that need a full CI run. process Issues and PRs related to the process subsystem. labels Oct 1, 2023
@GeoffreyBooth
GeoffreyBooth force-pushed the bypass-cjs-loader branch from a0fba47 to 4669340 Compare October 1, 2023 04:27
aduh95
aduh95 reviewed Oct 1, 2023
View reviewed changes
Comment thread lib/internal/modules/run_main.js Resolved

Uh oh!

There was an error while loading. Please reload this page.

@GeoffreyBooth
GeoffreyBooth force-pushed the bypass-cjs-loader branch from 4669340 to 6c6aefe Compare October 1, 2023 17:32
@GeoffreyBooth

GeoffreyBooth commented Oct 1, 2023 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member Author

So there are really two places where we resolve the input into a path: the resolveMainPath function, and this code within runMainESM:

    const main = path.isAbsolute(mainPath) ?
      pathToFileURL(mainPath).href : mainPath;

If we bypass or immediately return from resolveMainPath, then the mainPath input to runMainESM is the raw input from the CLI, like entry.js. And it usually won’t be absolute, so pathToFileURL isn’t getting called for it. So then we’re passing that input into esmLoader.import, which might work when the relative file path is parseable as a relative URL, which is most of the time—but not all of the time.

So I think either we undo the commit I just pushed, and always resolve the input into a path within resolveMainPath for both flows; or do something else. The more I think about this, the more it feels like runMainESM should always expect either an absolute file path or an absolute file URL, and code upstream of it is responsible for that conversion. We shouldn’t be resolving the input multiple times in multiple places. Thoughts @aduh95?

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

aduh95
aduh95 reviewed Oct 1, 2023
View reviewed changes
Comment thread lib/internal/modules/run_main.js Resolved

Uh oh!

There was an error while loading. Please reload this page.

@GeoffreyBooth

GeoffreyBooth commented Oct 2, 2023

Copy link
Copy Markdown
Member Author

@aduh95 I pushed some more commits, that undo the “streamline” commit, and add some tests and comments and improve an error message.

I’m open to being convinced otherwise, but it feels like a mistake to completely bypass resolveMainPath in ESM mode. Even if the esmLoader.import call within runMainESM somehow correctly parses a relative path as an URL (and please educate me on if that’s the case) we still should preserve the part of resolveMainPath that follows symlinks if --preserve-symlinks-main is not passed, right? We should presumably still support that in the new mode, right?

Assuming the above is all correct so far, I wanted a better error message for the “left off the file extension” case than just ENOENT: no such file or directory, lstat '/Users/geoffrey/Sites/node/test/fixtures/es-modules/package-without-type/index'. So I abstracted the “see if the resolution would’ve worked according to CommonJS rules” logic from esm/resolve.js and import it into the error path in run_main.js, so that node index prints an error message including Did you mean to import /Users/geoffrey/Sites/node/test/fixtures/es-modules/package-without-type/index.js? like we show for import specifiers that lack an extension. We were getting this message for free by passing through invalid input into esmLoader.import, but if we follow through with the toRealPath call in resolveMainPath then we need to handle it there.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@GeoffreyBooth
GeoffreyBooth force-pushed the bypass-cjs-loader branch from 6f61ca0 to 4cf437c Compare October 3, 2023 05:34
JakobJingleheimer
JakobJingleheimer approved these changes Oct 4, 2023
View reviewed changes

@JakobJingleheimer JakobJingleheimer left a comment

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Huzzah 🙂

A small nit: somewhere (I can't find the line now—on my mobile), it declares a typedef for default-type as a string: it's not any old string, it's an enum of specific strings. Ideally, those are numerated in the typedef.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
ljharb
ljharb reviewed Oct 5, 2023
View reviewed changes
Comment thread lib/internal/modules/esm/resolve.js Outdated
Comment on lines 1161 to 1164

@ljharb ljharb Oct 5, 2023

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
error.stack =
ArrayPrototypeShift(lines) + '\n' +
hint + '\n' +
ArrayPrototypeJoin(lines, '\n');
error.stack = `${ArrayPrototypeShift(lines)}\n${hint}\n${ArrayPrototypeJoin(lines, '\n')}`;

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
aduh95
aduh95 reviewed Oct 5, 2023
View reviewed changes
Comment thread lib/internal/modules/run_main.js Resolved

Uh oh!

There was an error while loading. Please reload this page.

aduh95
aduh95 reviewed Oct 5, 2023
View reviewed changes
Comment thread lib/internal/modules/run_main.js Resolved

Uh oh!

There was an error while loading. Please reload this page.

@GeoffreyBooth

GeoffreyBooth commented Oct 5, 2023

Copy link
Copy Markdown
Member Author

I reverted the optimization for the legacy flow. I don’t want to make changes to the legacy flow in this PR, I’m too nervous about such changes introducing bugs since the changes don’t break any tests when I’d expect that they should. I want to just land the new feature intended by this PR, bypassing the CommonJS loader under --default-type=module, and we can refactor the legacy flow in a separate PR (and add more tests for it).

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

GeoffreyBooth and others added 11 commits October 5, 2023 07:59
@GeoffreyBooth
esm: bypass CommonJS loader under --default-type
97b1966
@GeoffreyBooth
Streamline
30821db
@GeoffreyBooth
Revert "Streamline"
286c632
This reverts commit 6c6aefec5ede1070b2a17864075b2cc3d60718ee.
@GeoffreyBooth
Move/improve tests; decorate "not found" error to provide hint about …
4620842
…extension searching; fix lint
@GeoffreyBooth
Update docs
bdafa66
@GeoffreyBooth
Fix for Windows
83884e5
@GeoffreyBooth
Move out main re-resolution
162b6fa
@GeoffreyBooth
Optimize
22bddbd
@GeoffreyBooth
Revert "Optimize"
6c97b9a
This reverts commit 6d1a6e51118d1c4bd45cb21fad337ac2f87c8aa1.
@GeoffreyBooth @aduh95
Update lib/internal/modules/run_main.js
32aaabc
Co-authored-by: Antoine du Hamel <[email protected]>
@GeoffreyBooth
Return early if possible
038dfb8
@GeoffreyBooth GeoffreyBooth mentioned this pull request Oct 5, 2023
Proposal: Set --experimental-default-type mode by detecting ESM syntax in entry point #50043
Closed
@GeoffreyBooth GeoffreyBooth added commit-queue PRs queued for automated landing through the Commit Queue. commit-queue-squash PRs the Commit Queue should land as one squashed commit. labels Oct 5, 2023
@nodejs-github-bot nodejs-github-bot removed the commit-queue PRs queued for automated landing through the Commit Queue. label Oct 5, 2023
@nodejs-github-bot
nodejs-github-bot merged commit 19b470f into nodejs:main Oct 5, 2023
@nodejs-github-bot

nodejs-github-bot commented Oct 5, 2023

Copy link
Copy Markdown
Collaborator

Landed in 19b470f

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@GeoffreyBooth
GeoffreyBooth deleted the bypass-cjs-loader branch October 5, 2023 18:02
@RafaelGSS RafaelGSS mentioned this pull request Oct 9, 2023
2023-10-17, Version 21.0.0 (Current) #49870
Merged
@targos targos mentioned this pull request Nov 11, 2023
[v18.x] Backport most ESM and customization hook changes #50669
Closed
targos pushed a commit that referenced this pull request Nov 11, 2023
@GeoffreyBooth @targos
esm: bypass CommonJS loader under --default-type
4de838f
PR-URL: #49986
Reviewed-By: Jacob Smith <[email protected]>
Reviewed-By: Antoine du Hamel <[email protected]>
targos pushed a commit to targos/node that referenced this pull request Nov 11, 2023
@GeoffreyBooth @targos
esm: bypass CommonJS loader under --default-type
151e812
PR-URL: nodejs#49986
Reviewed-By: Jacob Smith <[email protected]>
Reviewed-By: Antoine du Hamel <[email protected]>
@targos targos mentioned this pull request Nov 12, 2023
v20.10.0 release proposal #50682
Merged
@targos targos added the backported-to-v18.x label Nov 23, 2023
targos pushed a commit that referenced this pull request Nov 23, 2023
@GeoffreyBooth @targos
esm: bypass CommonJS loader under --default-type
c3c945e
PR-URL: #49986
Backport-PR-URL: #50669
Reviewed-By: Jacob Smith <[email protected]>
Reviewed-By: Antoine du Hamel <[email protected]>
@targos targos mentioned this pull request Nov 28, 2023
v18.19.0 release proposal #50953
Merged
@juanarbol juanarbol mentioned this pull request Dec 6, 2023
2023-12-06, N|Solid v5.0.1 Iron Release nodesource/nsolid#41
Merged
ckerr added a commit to electron/electron that referenced this pull request Dec 7, 2023
@ckerr
chore: update feat_initialize_asar_support.patch
bcd8239
no code changes; patch just needed an update due to nearby upstream changes

Xref: nodejs/node#49986
ckerr added a commit to electron/electron that referenced this pull request Dec 7, 2023
@ckerr
chore: update chore_allow_the_node_entrypoint_to_be_a_builtin_module.…
88449ae
…patch

Xref: nodejs/node#49986

minor manual changes needed to sync with upstream change
codebytere pushed a commit to electron/electron that referenced this pull request Dec 8, 2023
@ckerr @codebytere
chore: update feat_initialize_asar_support.patch
943ccb7
no code changes; patch just needed an update due to nearby upstream changes

Xref: nodejs/node#49986
codebytere pushed a commit to electron/electron that referenced this pull request Dec 8, 2023
@ckerr @codebytere
chore: update chore_allow_the_node_entrypoint_to_be_a_builtin_module.…
3494aa6
…patch

Xref: nodejs/node#49986

minor manual changes needed to sync with upstream change
codebytere added a commit to electron/electron that referenced this pull request Dec 8, 2023
@codebytere
esm: bypass CommonJS loader under --default-type=module
19f12ca
nodejs/node#49986
codebytere added a commit to electron/electron that referenced this pull request Dec 11, 2023
@electron-roller @ckerr @codebytere
chore: bump node to v20.10.0 (main) (#40675)
890a557
* chore: bump node in DEPS to v20.10.0

* chore: update feat_initialize_asar_support.patch

no code changes; patch just needed an update due to nearby upstream changes

Xref: nodejs/node#49986

* chore: update pass_all_globals_through_require.patch

no manual changes; patch applied with fuzz

Xref: nodejs/node#49657

* chore: update refactor_allow_embedder_overriding_of_internal_fs_calls

Xref: nodejs/node#49912

no code changes; patch just needed an update due to nearby upstream changes

* chore: update chore_allow_the_node_entrypoint_to_be_a_builtin_module.patch

Xref: nodejs/node#49986

minor manual changes needed to sync with upstream change

* update fix_expose_the_built-in_electron_module_via_the_esm_loader.patch

Xref: nodejs/node#50096
Xref: nodejs/node#50314
in lib/internal/modules/esm/load.js, update the code that checks for
`format === 'electron'`. I'd like 👀 on this

Xref: nodejs/node#49657
add braces in lib/internal/modules/esm/translators.js to sync with upstream

* fix: lazyload fs in esm loaders to apply asar patches

* nodejs/node#50127
* nodejs/node#50096

* esm: jsdoc for modules code

nodejs/node#49523

* test: set test-cli-node-options as flaky

nodejs/node#50296

* deps: update c-ares to 1.20.1

nodejs/node#50082

* esm: bypass CommonJS loader under --default-type=module

nodejs/node#49986

* deps: update uvwasi to 0.0.19

nodejs/node#49908

* lib,test: do not hardcode Buffer.kMaxLength

nodejs/node#49876

* crypto: account for disabled SharedArrayBuffer

nodejs/node#50034

* test: fix edge snapshot stack traces

nodejs/node#49659

* src: generate snapshot with --predictable

nodejs/node#48749

* chore: fixup patch indices

* fs: throw errors from sync branches instead of separate implementations

nodejs/node#49913

* crypto: ensure valid point on elliptic curve in SubtleCrypto.importKey

nodejs/node#50234

* esm: detect ESM syntax in ambiguous JavaScrip

nodejs/node#50096

* fixup! test: fix edge snapshot stack traces

* esm: unflag extensionless ES module JavaScript and Wasm in module scope

nodejs/node#49974

* [tagged-ptr] Arrowify objects

https://chromium-review.googlesource.com/c/v8/v8/+/4705331

---------

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
Co-authored-by: Charles Kerr <[email protected]>
Co-authored-by: Shelley Vohr <[email protected]>
debadree25 pushed a commit to debadree25/node that referenced this pull request Apr 15, 2024
@GeoffreyBooth @debadree25
esm: bypass CommonJS loader under --default-type
672f793
PR-URL: nodejs#49986
Reviewed-By: Jacob Smith <[email protected]>
Reviewed-By: Antoine du Hamel <[email protected]>
sercher added a commit to sercher/graaljs that referenced this pull request Apr 25, 2024
@sercher
esm: bypass CommonJS loader under --default-type
a792185
PR-URL: nodejs/node#49986
Backport-PR-URL: nodejs/node#50669
Reviewed-By: Jacob Smith <[email protected]>
Reviewed-By: Antoine du Hamel <[email protected]>
sercher added a commit to sercher/graaljs that referenced this pull request Apr 25, 2024
@sercher
esm: bypass CommonJS loader under --default-type
fdf2ca1
PR-URL: nodejs/node#49986
Backport-PR-URL: nodejs/node#50669
Reviewed-By: Jacob Smith <[email protected]>
Reviewed-By: Antoine du Hamel <[email protected]>
bilbospocketses added a commit to bilbospocketses/ws-scrcpy-web that referenced this pull request Apr 18, 2026
@bilbospocketses
chore(multiplexer): drop Event/CloseEvent/MessageEvent polyfills, kee…
a912426
…p ErrorEvent

Node 24 (repo engines floor) has Event, CloseEvent, and MessageEvent as
globals — the typeof checks in Event.ts / CloseEventClass.ts /
MessageEventClass.ts always picked native on any supported runtime.
Inlining native constructors at the 5 Multiplexer/Message call sites and
deleting the three dead polyfill files.

ErrorEvent is NOT yet a Node global — verified on Node 24.14.1 via
'typeof ErrorEvent === "undefined"' (tracked upstream at
nodejs/node#49986; internal-only ErrorEvent lives in undici). Kept
ErrorEventClass.ts and rewrote it to extend native Event (it previously
extended the now-deleted Event2). Runtime smoke test confirms the
polyfill dispatches and listeners see error/message/filename/lineno/colno
fields correctly.

Net: -137/+18 across 6 files, 0 tsc errors, 89/89 tests pass, webpack
clean, generated .d.ts byte-identical (920 bytes).
bilbospocketses added a commit to bilbospocketses/ws-scrcpy-web that referenced this pull request Apr 27, 2026
@bilbospocketses
chore(multiplexer): drop Event/CloseEvent/MessageEvent polyfills, kee…
1cea742
…p ErrorEvent

Node 24 (repo engines floor) has Event, CloseEvent, and MessageEvent as
globals — the typeof checks in Event.ts / CloseEventClass.ts /
MessageEventClass.ts always picked native on any supported runtime.
Inlining native constructors at the 5 Multiplexer/Message call sites and
deleting the three dead polyfill files.

ErrorEvent is NOT yet a Node global — verified on Node 24.14.1 via
'typeof ErrorEvent === "undefined"' (tracked upstream at
nodejs/node#49986; internal-only ErrorEvent lives in undici). Kept
ErrorEventClass.ts and rewrote it to extend native Event (it previously
extended the now-deleted Event2). Runtime smoke test confirms the
polyfill dispatches and listeners see error/message/filename/lineno/colno
fields correctly.

Net: -137/+18 across 6 files, 0 tsc errors, 89/89 tests pass, webpack
clean, generated .d.ts byte-identical (920 bytes).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@ljharb ljharb ljharb left review comments
@JakobJingleheimer JakobJingleheimer JakobJingleheimer approved these changes
@aduh95 aduh95 aduh95 approved these changes

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

author ready PRs with CI started, the required approvals, and no outstanding review comments. cli Issues and PRs related to the Node.js command-line interface. commit-queue-squash PRs the Commit Queue should land as one squashed commit. esm Issues and PRs related to the ECMAScript Modules implementation. module Issues and PRs related to the module subsystem. needs-ci PRs that need a full CI run. process Issues and PRs related to the process subsystem.

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Uh oh!

There was an error while loading. Please reload this page.

6 participants

@GeoffreyBooth @nodejs-github-bot @ljharb @JakobJingleheimer @aduh95 @targos
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.