Skip to content
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

feat: import.meta.resolve() #15074

Merged
merged 24 commits into from
Jul 18, 2022
Merged

Conversation

bartlomieju
Copy link
Member

@bartlomieju bartlomieju commented Jul 4, 2022

Opening for a discussion purposes.

// meta.js
console.log("Resolving ./foo.js", import.meta.resolve("./foo.js"));
$ deno run meta.js
Resolving ./foo.js file:///Users/ib/dev/deno/foo.js
Resolving ./foo.js from ./bar.js file:///Users/ib/dev/deno/foo.js

@guybedford I'm a bit surprised in Node's behavior:

$ node --experimental-import-meta-resolve meta.mjs
I am file:///Users/ib/dev/deno/meta.mjs [Object: null prototype] {
  resolve: [AsyncFunction: resolve],
  url: 'file:///Users/ib/dev/deno/meta.mjs'
}
node:internal/errors:466
    ErrorCaptureStackTrace(err);
    ^

Error [ERR_MODULE_NOT_FOUND]: Cannot find module '/Users/ib/dev/deno/foo.js' imported from /Users/ib/dev/deno/meta.mjs
    at new NodeError (node:internal/errors:377:5)
    at finalizeResolution (node:internal/modules/esm/resolve:405:11)
    at moduleResolve (node:internal/modules/esm/resolve:966:10)
    at defaultResolve (node:internal/modules/esm/resolve:1174:11)
    at ESMLoader.resolve (node:internal/modules/esm/loader:605:30)
    at Object.resolve (node:internal/modules/esm/initialize_import_meta:15:26)
    at file:///Users/ib/dev/deno/meta.mjs:2:53
    at ModuleJob.run (node:internal/modules/esm/module_job:198:25)
    at async Promise.all (index 0)
    at async ESMLoader.import (node:internal/modules/esm/loader:409:24) {
  code: 'ERR_MODULE_NOT_FOUND'
}

Node.js v18.1.0

I would have thought that this function is for pure resolution and it won't touch file system to check for the existence of a specifier we're trying to resolve.

Closes #7296

@bartlomieju bartlomieju requested a review from lucacasonato July 4, 2022 21:19
@lucacasonato
Copy link
Member

This should be sync. HTML spec is sync.

@bartlomieju
Copy link
Member Author

This should be sync. HTML spec is sync.

That's fine for me, I'll rework the PR after fixing main branch

@bartlomieju
Copy link
Member Author

@lucacasonato I've reworked it to be sync, PTAL

@guybedford
Copy link
Contributor

@bartlomieju the reason for the Node.js behaviour is because Node.js will still apply the realpath algorithm to resolutions, which in turn throws. I agree it's not ideal - one thing we could do is catch any not found errors and rethrow them at load time rather. Perhaps realpathing should be handled more like redirects as well in being the response URL not the request URL, to get even more alignment with the web, despite the pains of that in double instancing. I can possibly try to push those two changes through Node.js process.

@bartlomieju
Copy link
Member Author

That makes it clear now, thanks for a thorough explanation. Since it already diverges from the spec by returning a promise I think it's okay for the behavior to stay as is, but would be great to have it documented.

@guybedford
Copy link
Contributor

We are actively working on aligning on a sync resolver, it just will take some time.

core/bindings.rs Outdated
};
match loader.resolve(
&specifier.to_rust_string_lossy(tc_scope),
&referrer,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens when the referrer is an invalid URL? That might not be tested for the core resolver?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

loader.resolve() raises an error that is forwarded to JS

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add a test? For example trying to resolve an invalid URL.

@guybedford
Copy link
Contributor

To be transparent there is still some uncertainty about the second argument - whatwg/html#8074 (comment).

@bartlomieju
Copy link
Member Author

To be transparent there is still some uncertainty about the second argument - whatwg/html#8074 (comment).

I think it would be safer for us, to only support the first argument for now since it's a living standard right now.

@bartlomieju
Copy link
Member Author

I've reverted addition of the second argument since it is not yet specced. @lucacasonato please review.

@bartlomieju bartlomieju requested a review from lucacasonato July 14, 2022 15:39
core/bindings.rs Outdated Show resolved Hide resolved
core/bindings.rs Outdated Show resolved Hide resolved
Copy link
Member

@lucacasonato lucacasonato left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@bartlomieju bartlomieju merged commit 999cbfb into denoland:main Jul 18, 2022
@bartlomieju bartlomieju deleted the import_meta_resolve branch July 18, 2022 18:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

import.meta.resolve implementation
6 participants