Support for resolving modules from folder paths
fabiospampinato opened this issue · 8 comments
I spent some time trying to resolve a dependency from a URL like the following, which was a bit confusing because I have that dependency listed in package.json
, installed in node_modules
and I can import it from the REPL, but this module can't find it:
url.pathToFileURL(process.cwd());
But apparently using a folder's path as the starting point is not supported, while something like this works:
url.pathToFileURL(path.join(process.cwd(), "index.js"));
IMO it'd be nice if resolving from a folder was just supported also, or at least if this scenario was documented.
Supporting both folders and files as the base is ambiguous: if both foo/index.js
and foo/bar/index.js
exist, what does resolve("./index.js", "foo/bar")
resolve to?
The readme currently says that the second parameter is "the absolute parent module URL", maybe it should either be made more prominent or more explicit that a module is a file 🤔
I don't see how this issue is here?
Anyway, yeah, its the same as browsers. It matters where you resolve from
In browsers/Node.js import.meta.resolve
takes a single parameter, so you don't really "notice" that the parent is the file URL and not the folder URL.
I don't see how this issue is here?
Right this is maybe out of place 🤔 However, the description is "Resolve things like Node.js.", but when I fire up a REPL and import something what file is Node resolving things from?
https://github.com/nodejs/node/blob/1b60054fffc0c67a711cdf3efbcc8f44afab0ce2/lib/repl.js#L461
pathToFileURL(path.join(process.cwd(), 'repl'))
, apparently
I think youre looking for import.meta.url? Thats whats also in the docs here as a recommendation.
In ESM i always use that; basically never process.cwd
@wooorm yeah but the REPL is a weird environment:
Anyway, closing this to keep things tidy. Worth thinking about special-casing what happens if the input path is a folder for convenience, either by throwing with a more specific reason or by doing something else, imo.
process.cwd()
is needed in situations where for example you need to load some plugins, like you do prettier --plugin whatever
, and that whatever
plugin should be loaded from the process.cwd()
basically.
IMO this is all more about how URLs resolve. Where <a href="x">
goes to. I don’t see the web changing that. It depends on whether you’re on https://example.com/y
or https://example.com/y/
:
new URL('x', 'https://example.com/y').href // 'https://example.com/x'
new URL('x', 'https://example.com/y/').href // 'https://example.com/y/x'
process.cwd
You can solve it with url.pathToFileURL(process.cwd() + path.sep)
.
Anyway, this is a copy of Node. Changes go in Node.
In browsers/Node.js import.meta.resolve takes a single parameter, so you don't really "notice" that the parent is the file URL and not the folder URL.
— @nicolo-ribaudo
Small nit: they do accept a second parameter. They default to import.meta.url
but you can pass any URL. That is impossible to polyfill, so it must be passed explicitly here.