-
-
Notifications
You must be signed in to change notification settings - Fork 34.2k
Closed
Labels
esmIssues and PRs related to the ECMAScript Modules implementation.Issues and PRs related to the ECMAScript Modules implementation.experimentalIssues and PRs related to experimental features.Issues and PRs related to experimental features.feature requestIssues that request new features to be added to Node.js.Issues that request new features to be added to Node.js.loadersIssues and PRs related to ES module loadersIssues and PRs related to ES module loadersmoduleIssues and PRs related to the module subsystem.Issues and PRs related to the module subsystem.
Description
What is the problem this feature will solve?
I thought that the --experimental-specifier-resolution=node CLI option was made to emulate legacy cjs resolution algorithm. However the legacy cjs module loader can handle extension-less files whereas which is not the case with this CLI option:
> cat yo
console.log("yo");
> node yo
yo
> node --experimental-specifier-resolution=node yo
(node:33081) ExperimentalWarning: The Node.js specifier resolution in ESM is experimental.
(Use `node --trace-warnings ...` to show where the warning was created)
node:internal/errors:464
ErrorCaptureStackTrace(err);
^
TypeError [ERR_INVALID_MODULE_SPECIFIER]: Invalid module "file:///Users/soft/Desktop/workspace/appmap-agent-js/yo"
at new NodeError (node:internal/errors:371:5)
at ESMLoader.load (node:internal/modules/esm/loader:380:13)
at async ESMLoader.moduleProvider (node:internal/modules/esm/loader:280:47)
at async link (node:internal/modules/esm/module_job:70:21) {
code: 'ERR_INVALID_MODULE_SPECIFIER'
}
Node.js v17.3.0These extension-less files are actually common in the bin directory of many popular projects -- eg: mocha. This makes it hard to use --experimental-loader on these projects because the below command fails for the same reason as above:
NODE_OPTIONS="--experimental-loader=./loader.mjs --experimental-specifier-resolution=node" npx mochaWhat is the feature you are proposing to solve the problem?
Consider extension-less files as commonjs modules as the legacy cjs loader does. This is can done be done easily by modifying legacyExtensionFormatMap in lib/internal/modules/esm/get_format.js:
const legacyExtensionFormatMap = {
'__proto__': null,
'.cjs': 'commonjs',
'.js': 'commonjs',
'.json': 'commonjs',
'.mjs': 'module',
'.node': 'commonjs',
'': 'commonjs' // Added line
};Is there a good reason why this has not been considered?
What alternatives have you considered?
- Resolve the module in the loader provided by
--experimental-loaderand do not pass it to the default loader. This is a bazooka solution because the loader API basically enables to write one's own module resolution algorithm. We don't want to emulate the entire module resolution algorithm for such a minimal change. - Rename and change the target of the symbolic link installed by npm to add a
.jsextension. This must happen in a preloaded module. It is extremely hacky and does not work on windows.
codingedgar, joemullenix-ks, machineghost, pariesz and Pkmmte
Metadata
Metadata
Assignees
Labels
esmIssues and PRs related to the ECMAScript Modules implementation.Issues and PRs related to the ECMAScript Modules implementation.experimentalIssues and PRs related to experimental features.Issues and PRs related to experimental features.feature requestIssues that request new features to be added to Node.js.Issues that request new features to be added to Node.js.loadersIssues and PRs related to ES module loadersIssues and PRs related to ES module loadersmoduleIssues and PRs related to the module subsystem.Issues and PRs related to the module subsystem.