Skip to content

Conversation

@GeoffreyBooth
Copy link
Member

@GeoffreyBooth GeoffreyBooth commented Sep 26, 2023

This PR contains work by @LiviaMedeiros, @JakobJingleheimer, @bmeck adapted from #49531, #49540, #49295, #41552, #31388.

This PR implements most of the proposal in #49432. It creates a new flag, --experimental-default-type, which supports values commonjs (the default) or module. Under --experimental-default-type=module, Node.js interprets the following as ES modules:

  • String input provided via --eval or STDIN, if --input-type is unspecified.

  • Files ending in .js or with no extension, if there is no package.json file present in the same folder or any parent folder.

  • Files ending in .js or with no extension, if the nearest parent package.json field lacks a type field; unless the folder is inside a node_modules folder.

Extensionless files are interpreted as Wasm if --experimental-wasm-modules is passed and the file contains the “magic bytes” Wasm header.

The ESM loader is used for all entry points, and we don’t pass through Module.runMain. Under this flag, we no longer support monkey-patching of that method by files loaded via --require.

This PR does not implement the “parse the entry point as a URL” part of #49432, as there are still some design decisions to be made around that and it’s substantial enough to warrant being implemented as a separate PR.

This is related to #49629 and linked PRs, which include the above behaviors for extensionless files but don’t require a flag. I think we can potentially ship that change on its own, separate from making this flag the new default behavior, because extensionless files currently error in module scopes. I’d prefer to ship it behind the --experimental-default-type flag first to work out any kinks before splitting it out to not require any flag.

If people don’t mind, I’d like if this PR thread can focus on the implementation. If anyone has any thoughts on the design or intentions behind this, there’s already a detailed thread for that at #49432.

cc @nodejs/loaders @nodejs/wasi @nodejs/startup @nodejs/tsc

Notable change

The new flag --experimental-default-type can be used to flip the default module system used by Node.js. Input that is already explicitly defined as ES modules or CommonJS, such as by a package.json "type" field or .mjs/.cjs file extension or the --input-type flag, is unaffected. What is currently implicitly CommonJS would instead be interpreted as ES modules under --experimental-default-type=module:

  • String input provided via --eval or STDIN, if --input-type is unspecified.

  • Files ending in .js or with no extension, if there is no package.json file present in the same folder or any parent folder.

  • Files ending in .js or with no extension, if the nearest parent package.json field lacks a type field; unless the folder is inside a node_modules folder.

In addition, extensionless files are interpreted as Wasm if --experimental-wasm-modules is passed and the file contains the “magic bytes” Wasm header.

@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 Sep 26, 2023
@nodejs-github-bot
Copy link
Collaborator

Review requested:

  • @nodejs/loaders

@nodejs-github-bot nodejs-github-bot added lib / src Issues and PRs related to general changes in the lib or src directory. needs-ci PRs that need a full CI run. labels Sep 26, 2023
Copy link
Contributor

@guybedford guybedford left a comment

Choose a reason for hiding this comment

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

Thanks @GeoffreyBooth for continuing to push this work, this seems like a step in the right direction to me.

My only suggestion would be considering an alternative flag name like --default-type as an experimental flag or --experimental-default-type so that it is clear from the start that it is not an authoritative flag.

@mcollina mcollina added the notable-change PRs with changes that should be highlighted in changelogs. label Sep 26, 2023
@github-actions

This comment was marked as resolved.

@GeoffreyBooth GeoffreyBooth force-pushed the flip-defaults-to-esm branch 2 times, most recently from bf5c677 to 6f0e209 Compare September 26, 2023 16:15
Copy link
Contributor

@guybedford guybedford left a comment

Choose a reason for hiding this comment

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

Marking for approval conditional on resolving the naming discussion.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

author ready PRs that have at least one approval, no pending requests for changes, and a CI started. cli Issues and PRs related to the Node.js command line interface. commit-queue-squash Add this label to instruct the Commit Queue to squash all the PR commits into the first one. esm Issues and PRs related to the ECMAScript Modules implementation. lib / src Issues and PRs related to general changes in the lib or src directory. module Issues and PRs related to the module subsystem. needs-ci PRs that need a full CI run. notable-change PRs with changes that should be highlighted in changelogs.

Projects

None yet

Development

Successfully merging this pull request may close these issues.