-
Notifications
You must be signed in to change notification settings - Fork 28.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Subpath imports with "imports" field in CommonJS does not try to resolve with extensions #51492
Comments
The docs say the following: Lines 486 to 490 in 37ba7a3
Lines 404 to 410 in 37ba7a3
So the behavior you describe is working as documented. I'm not sure we should change that, extension guessing is not worth the trouble IMO, explicit is better than implicit. @nodejs/loaders thoughts? |
Extension guessing adds a lot of complexity, both for us and for other tools that mimic Node’s behavior, and incurs a performance cost. Adding it to |
This diverges the resolution tree static to the package.json. It should not be done and was discussed in Modules WG. Tools etc. would no longer guarantee lookup interoperability due to divergence of file support and various design aspects like conditions don't make sense. |
I understand what you're saying. The implementation also looks clean. And runtime costs are there if that was. In CommonJS, developers have been familiar with to writing import paths without extensions. I've tried to recreate "extension guessing" with array notation in imports field. It does not work because of import path resolution does not fallback, same as #37928 says. // package.json
//...
"imports": {
"#*": ["./src/*.js", "./src/*"]
}
//...
// src/index.js
const sub = require("#sub"); // works
const subExt = require("#sub.js"); // error, "sub.js.js" is not found Anyway, it is not analogous in CJS, confusing behavior for users migrate alias notations from other tools. If Of course, it's understandable to think of new ways to use Subpath. However, in that case, I think it would be better to have an explanation for this surprising behavior in CJS. 📝 partial workaround// package.json
//...
"imports": {
"#*": ["./src/*.js"], // cannot guess, just point *.js. but we can write other extension explicitly
// "#*": ["./src/*", "./src/*.js", "./src/*/index.js"], // not works, tries first pattern and raise `module not found`
"#*.js": ["./src/*.js"]
// repeat each of extensions you need
// This can be a acceptable choice
// for users who want to define several aliases that map to things like "src" or the root directory,
// but it would better if there was a candidate fallback behavior.
}
//...
// src/index.js
const sub = require("#sub"); // works
const subExt = require("#sub.js"); // works |
The thing is that because |
CommonJS works with explicit extensions too. If you're going to use |
Thank you. Both seem reasonable to me. It seems likely that "extension everywhere" might become a generally applicable option. I believe this provides a good path towards a world where the import field in import path mapping is a single source of truth. How can we explicitly indicate that there's no extension guessing also on the imports side? |
I agree updating the documentation is warranted, if you were surprised by this behavior, chances are that others will be to. If you can send a PR, that'd be lovely, otherwise I'll try to find the time later this week unless someone beats me to it. |
I got hit by this too, not because I was trying to restore 'extension guessing' like CJS, but because I was trying to conditionally resolve Yes, I'm aware that Metro (the react-native bundler) handles these extensions, but that does me no good if I want to have a package that supports using RN/metro for native, but a different bundler for web. The way this is implemented, I would have to either: This was certainly surprising behavior to me, and clearly others. I was really hoping the Any suggestions on how to achieve the above, without writing a plugin for every bundler? |
Cross-posting from wooorm/import-meta-resolve#20, since this is really a node issue.
|
There has been no activity on this feature request for 5 months. To help maintain relevant open issues, please add the
never-stale
|
What is the problem this feature will solve?
with package.json:
and src/index.js:
src/fn.js:
and runs:
got an error,
MODULE_NOT_FOUND
What is the feature you are proposing to solve the problem?
As with relative paths, try resolving with registered extensions. This provides similarity between aliased and non-aliased import paths.
What alternatives have you considered?
In the section https://nodejs.org/api/packages.html#subpath-imports or https://nodejs.org/api/packages.html#subpath-patterns, note that the runtime will not try to resolve requested path with registered extensions in CommonJS.
The text was updated successfully, but these errors were encountered: