-
Notifications
You must be signed in to change notification settings - Fork 72
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
Trailing slashes #244
Comments
Once difference to note is that when that package has an "exports" field, the However, canonicalizing trailing slashes still seems like the proper thing to do. |
This is no longer the case for the ES modules implementation of Node.js, and a special ERR_UNSUPPORTED_DIR_IMPORT error is thrown instead. This has been part of the effort of deprecating some of the magic around module resolution by not including support for directory resolution in the ES modules resolver implementation to try create alignment with browser resolution. There is a lot to this conversation though, happy to flesh out any aspects further as necessary. |
@guybedford I think it's slightly different in that ESM in Node.js doesn't support directory imports altogether anymore, regardless of whether it was specified with a trailing slash? |
@RReverser yes you are correct this is based on strictly checking if the file is a directory not the trailing slash. So in Node.js a trailing slash that is not a directory would throw MODULE_NOT_FOUND instead. But you can still resolve a directory import for the main for CJS, eg via There is a separate deprecation PR currently in progress to deprecate this behaviour for ES modules though as well, in ensuring "main" always points to a complete path in the page. Regardless, Node.js fully deprecates the resolution of trailing slashes, which is the important point to note here. They simply can't resolve in Node.js anymore. |
This isn’t accurate - node has not in any way deprecated trailing slashes in CJS, for packages that lack an “exports” field. That may not be relevant to import maps, though, which are for ESM. |
@ljharb |
@guybedford agreed, but "fully deprecated" implies "with |
Also probably worth mentioning But yeah, to be honest, I didn't know Node chose not to support directory -> main file imports by default in ESM syntax, not even via |
I think I'm OK not supporting this, but if we have people using import maps in the wild where this is an issue, please let me know (preferably with a link to the site). |
@domenic FWIW the deprecation path is moving now in Node.js to fully disable trailing slash imports for ESM. |
@RReverser pointed out to me today that in Node.js, you can do either
require("lodash")
orrequire("lodash/")
, and both will map to the lodash package's main module.Similarly, in Node.js you can do either
require("./directory")
orrequire("./directory/")
, and this will look for the"main"
field in./directory/package.json
and require that module.With import maps, these trailing slash variants are not possible to remap in the same way. We currently require trailing slashes to match, so you can do
"lodash/": "/node_modules/lodash/"
and"./directory/": "./some/other/directory/"
. But then, importing those will give URLs likehttps://example.com/node_modules/lodash/
, which is not what you want; you wanted the URL to behttps://example.com/node_modules/lodash/main.mjs
.Another aspect to consider is if we introduce
import.meta.resolve()
. What should the result ofimport.meta.resolve("lodash/fp/..")
be? As currently proposed, it would be whatever URL"lodash/"
maps to. Which, per the above, is not so useful.So the first question is, do we care about this case? I'm inclined to take a wait-and-see approach. In particular, my initial instinct is that even though Node has two ways to require the same module,
"lodash"
and"lodash/"
, maybe it's OK that on the web only the first way works. I'd be open to changing this opinion as we see more people running into issues in the wild.Then, if we did want to address this, how would we? Simply lifting the "slashes must match" restriction is not great, because what if you want both
"lodash/" -> </node_modules/lodash/main.mjs>
and"lodash/foo.mjs" -> </node_modules/lodash/foo.mjs>
? You wouldn't be able to get both.One route for addressing this, which is attractive to me, might be to try to canonicalize all trailing slashes in import specifiers away. That is,
"lodash/"
literally means the same thing as"lodash"
. This is trickier for cases like"/directory/"
; it'd be a breaking change (but maybe a web-compatible one?) to always treat that the same as"/directory"
, i.e. change it to by default request the URL</directory>
instead of the URL</directory/>
. Maybe we could only impose the normalization when an import map gets involved? But that might be a bit messy.The text was updated successfully, but these errors were encountered: