wooorm/import-meta-resolve

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 🤔

wooorm commented

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?

wooorm commented

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:

Screen Shot 2023-12-12 at 18 37 36

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.

wooorm commented

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.