Uh oh!
There was an error while loading. Please reload this page.
esm: unflag import.meta.resolve - #33464
Conversation
I'm concerned about cc @nodejs/modules-active-members |
guybedford
commented
May 19, 2020
@ljharb it is not importable because the difference between |
guybedford
commented
May 19, 2020
Other than that though, the resolvers are equivalent. |
guybedford
commented
May 19, 2020
Other useful use cases for this include resolving |
I think that if it's useful to be able to resolve non-importable paths (ie is, in both CJS and ESM, it's just not possible right now in CJS), then we need to pursue an API for both CJS and ESM to do so. The point of |
devsnek
commented
May 19, 2020
this was originally flagged because we wanted to work with the web to have some isomorphism here, is that still a goal? |
guybedford
commented
May 19, 2020
@ljharb the benefit of a singular API is static analyzability - I say this having done a lot of these types of analyses in node-file-trace and ncc for Vercel. ESM is more statically analyzable than CJS - we didn't have to restrict ourselves in the development of ESM to making it match CommonJS in terms of analyzability. You seem to be applying the same sort of argument in disallowing features which improve analyzability. I am not against a Ideally we can avoid seeing problems as mutually exclusive and appreciate that there are different benefits to different approaches. I don't think we should restrict the |
guybedford
commented
May 19, 2020
@devsnek if we wait for the web we will grow old in the mean time, and ship ESM without full features. |
@guybedford i'm not opposed to the ESM version of it being chained off of |
devsnek
commented
May 19, 2020
The resolver's job is to turn a specifier and a referrer into an absolute url. knowing whether that url can actually be loaded is separate, and requires a full import lifecycle. |
ljharb
commented
May 19, 2020
@devsnek while i don’t think that’s true in node, where all importable URLs are synchronously resolvable, the ESM API should then be async. The entire point of a resolve api is so you can load the result. |
devsnek
commented
May 19, 2020
no the point is to pass the resolved url to the source loader, which is the only part of node that understands whether or not the url can be loaded |
hybrist
commented
May 19, 2020
I agree with @devsnek here. It's already not fully true that a string generated from |
hybrist
left a comment
There was a problem hiding this comment.
Given the description, it looks like one of two things are true:
- Resolving
pkg/doesn't honor./inexports, e.g. for people who want to do things like{"./": "./lib/"}. - This isn't a reliable way to get the root
package.jsonbecause it may accidentally resolve to./lib/packag.json.
I'm still in support of unflagging this but I currently assume that (2) is the case. I would have concerns if this is (1).
ljharb
commented
May 19, 2020
In the absence of loaders (the default and common case), and assuming disk operations succeed (also the common case), require.resolve is requireable, and i expect (and i maintain, the common expectation will be) import.meta.resolve to be importable. |
hybrist
commented
May 19, 2020
That assumes the HTTP-based imports will never be a common thing. To me that's too big a bet to enshrine in our APIs. Especially given that it absolutely is a common thing in browsers and browsers are by far the most popular JS [module] runtime. I'm not saying I'm 100% sure that they will become common, just that I wouldn't want to design our APIs based on the assumption that they won't. |
ljharb
commented
May 19, 2020
I don’t think it will ever be a good idea nor a possible thing, but that still doesn’t mean this api should ever resolve a path that is known to be impossible to import. |
devsnek
commented
May 19, 2020
@ljharb it sounds like you're asking that the default resolver fail if it knows the resolved url won't be loadable? |
ljharb
commented
May 19, 2020
@devsnek yes, just like |
devsnek
commented
May 19, 2020
@ljharb that's not a change that would be made to |
@devsnek ok - why would the default ESM resolver allow (also, the point of |
devsnek
commented
May 19, 2020
@ljharb |
MylesBorins
commented
May 20, 2020
Has there been any signal from upstream that a standardized version of this is ready to land in browsers? I'm uncomfortable unflagging this until that point. While we do have TLA, it is still behind a flag... this to me seems premature |
bmeck
commented
May 20, 2020
I believe the closes thing is Compartments have a resolve hook. It does not currently allow you to reflect on your current context, but that was talked about in the last 2 meetings as a potential fix for a problem with polyfills. |
jasnell
commented
May 20, 2020
Given that |
guybedford
commented
May 20, 2020
As just discussed in the modules meeting, there was resistance to implementing this without having exact implementation equality with |
GeoffreyBooth
commented
May 20, 2020
I think there is consensus that we can ship an equivalent: import{resolveURL}from'module';// <---- thisimport{promisesasfs}from'fs';constpkgUrl=awaitresolveURL(import.meta,'pkg/');constpjson=awaitfs.readFile(newURL('package.json',pkgUrl));And potentially add it to |
Now that TLA has landed, the workflows around this are really quite nice.
For example, to load the package.json file from an external package one can write:
Note: this is in no way meant to be a full solution to the other issue discussion, where @ljharb has suggested some directions forward.
Other examples were included in the original PR - #31032.
I do think unflagging is important as this is a critical feature for ESM to ensure it has the
require.resolveuse cases supported.Checklist
make -j4 test(UNIX), orvcbuild test(Windows) passes