Description
Building off of #49295 (comment) and #31415, we’re considering a new mode, probably enabled by flag, where all of the current places where Node defaults to CommonJS would instead default to ESM. One of the trickiest questions to answer for defining such a new mode is how extensionless entry points should be handled.
In an early version of the ESM implementation, extensionless entry points followed the same interpretation of .js
files; if they were in a "type": "module"
package.json
scope, they were run as ESM, otherwise they were run as CommonJS. They couldn’t be referenced via import
; extensionless support was limited to entry points, to handle the CLI tool use case without complicating the resolution algorithm. #31415 removed this ESM extensionless entry point support because there was desire to someday permit extensionless entry points to be not just ESM JavaScript but also Wasm. We haven’t followed up since.
There is a strong desire from users for the ability to write CLI apps or “shell scripts” using ESM, without needing things like symlinks or CommonJS wrappers in order to enable extensionless entry points being interpreted as ESM. I can think of two potential ways to enable such, which we could limit to being enabled by our new flag:
-
Extensionless is just always ESM in a
"type": "module"
scope (or in this new ESM-first mode, outside of a"type": "commonjs"
scope). There’s simply no ability for extensionless Wasm entry points; Node.js is a JavaScript runtime, after all. This tracks how there’s also currently no support for extensionless native/.node
-file entry points. -
Use the Wasm magic byte to disambiguate between Wasm and ESM entry. Either always check for magic byte before trying to parse, or check after failure to parse as ESM JavaScript.
Are there other approaches?
I think we need to find some way to enable this use case, either behind this new “ESM by default” flag or in Node generally. It keeps coming up and the pressure from users will only increase as ESM adoption continues. @LiviaMedeiros @nodejs/loaders @nodejs/wasi @nodejs/tsc