`node --loader` treats entrypoint as ESM when should be loaded as CJS

  • Version: 14.1.0
  • Platform: Ubuntu 19
  • Subsystem: entrypoint handling

What steps will reproduce the bug?

mkdir empty-dir
cd empty-dir
echo '{}' > package.json
touch entrypoint
touch hooks.mjs
node ./entrypoint # <-- no error; no output; exit code 0
node --loader ./hooks.mjs ./entrypoint # <-- error that "" is not a recognized file extension by the default ESM loader

How often does it reproduce? Is there a required condition?

Always

What is the expected behavior?

./entrypoint is executed as a CommonJS module whether or not --loader is passed.

What do you see instead?

When --loader is passed, node always tries to load entrypoint scripts as ESM, ignoring that package.json wants the file to be treated as CJS. This does not happen when --loader is omitted, suggesting that this behavior is a bug.

"" is not a recognized file extension by the default ESM loader
(node:26067) ExperimentalWarning: --experimental-loader is an experimental feature. This feature could change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
internal/modules/run_main.js:54
    internalBinding('errors').triggerUncaughtException(
                              ^

TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension "" for /d/Personal-dev/@TypeStrong/ts-node-repros/empty-dir/entrypoint
    at Loader.defaultGetFormat [as _getFormat] (internal/modules/esm/get_format.js:65:15)
    at Loader.getFormat (internal/modules/esm/loader.js:113:42)
    at Loader.getModuleJob (internal/modules/esm/loader.js:244:31)
    at async Loader.import (internal/modules/esm/loader.js:178:17) {
  code: 'ERR_UNKNOWN_FILE_EXTENSION'
}

Additional information

#33223