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

import.meta.url #26

Open
ljharb opened this issue Dec 15, 2020 · 12 comments
Open

import.meta.url #26

ljharb opened this issue Dec 15, 2020 · 12 comments
Labels
host environment Questions to be answered in each host environment
Milestone

Comments

@ljharb
Copy link
Member

ljharb commented Dec 15, 2020

It seems very undesirable to me to have different modules result in the same import.meta.url - i see that value as the thing i can import to get the same module back. Why would it make sense to have a module block’s url match the document that contains it (but may not export it)?

@littledan
Copy link
Member

One motivating use case is things like asset references through new URL(..., import.meta.url). It's also important that we resolve relative paths included in imports inside of module blocks properly (which IMO should be based on the path to the module enclosing the module block), though this isn't necessarily the same thing that's reflected in import.meta.url

@ljharb Can you say why it's undesirable that import.meta.url would be the same for different modules? Did you have another idea for what import.meta.url would be in module blocks?

@ljharb
Copy link
Member Author

ljharb commented Dec 15, 2020

For one, because I'd expect it to occasionally be used as a cache key.

I don't know what I'd expect it to be in module blocks - null or undefined seems like a reasonable answer to me tho.

@nicolo-ribaudo
Copy link
Member

nicolo-ribaudo commented Dec 15, 2020

Would it make sense for import.meta.url to contain a fragment pointing to the source location, which is unique?

For example:

console.log(import.meta.url); // https://example.com/index.js

let mod = module {
  console.log(import.meta.url); // https://example.com/index.js#L3C10
};

(where L3C10 means "line 3 column 10")

By doing so, new URL(..., import.meta.url) would still work, but import.meta.url is guaranteed to be unique for every module.

null or undefined seems like a reasonable answer to me tho.

This wouldn't still work for cache keys.

@ljharb
Copy link
Member Author

ljharb commented Dec 15, 2020

Indeed nullish wouldn't work for caching, but at least it would avoid caching the wrong thing.

@surma
Copy link
Member

surma commented Dec 15, 2020

@nicolo-ribaudo I like your suggestions.

@ljharb Any other concerns regarding inheriting import.meta.url from the surrounding module?

@ljharb
Copy link
Member Author

ljharb commented Dec 15, 2020

@surma i mean, i'm not sure what more concerns are needed besides "a URL for a resource is supposed to point to that resource" ¯_(ツ)_/¯ like duplicating an ID in the DOM, it kind of defeats the point of a uniform resource locator if it can't uniformly locate a resource.

@littledan
Copy link
Member

littledan commented Dec 27, 2020

A bit of a tangential idea: if we made a URL pattern like https://example.com/index.js#L3C10 be able to not just serve as import.meta.url but also be available for imports, then module blocks could import each other and therefore be used as a bundling format. (However, this would probably mean that we'd want to cache by source location, not generating a new module each time it's executed.)

There's a slight compatibility risk here, as # could currently be used in a module specifier, and is basically ignored (but does show up in import.meta.url) but this feature is not very useful, and I bet it we could redefine it in practice, especially if we put some funky prefix on it like scroll to test fragment has (e.g., https://example.com/index.js#?loc=L3C10).

What would people think about this direction?

@nicolo-ribaudo
Copy link
Member

That would break at runtime whenever code is bundled, concatenated, minified, or compiled.
Also, when running Prettier (or any other formatter) on your code you would have to update all the imports to inline modules, since their source location change.

@littledan
Copy link
Member

littledan commented Dec 27, 2020

Right, offset is probably not a good naming. What if, instead, the name can either be explicit (like module "name" { } to put it at #name) to allow stability? If the name is omitted, I am not sure how the default should be chosen--maybe it is OK to be unstable in that case (but maybe not quite as bad, e.g., indicating that it is the nth module block in the file). Or, an explicit name could be mandatory in the syntax.

@littledan
Copy link
Member

On second thought, that direction might be a not-so-great one. For example, it would basically rule out defining a module block inside of eval.

@littledan
Copy link
Member

A further problem with a form of module blocks based on strings is that it makes lifetime management more complicated. Strings, unlike objects, can be reconstructed "from scratch", so there is no reference that the lifetime of the string can be associated with. If there is a literal fragment explicitly in the JS (ruling out dynamic eval and non-parser-generated script tags), then it would be possible to re-fetch, but if we want to allow dynamic generation, you could imagine a UUID in the fragment. But then, it's not clear how long this should stay alive--unlike blobs, it would be incorrect to just let this fall out of cache.

Overall, for these reasons, I think it wouldn't be viable to make it so that you can import the import.meta.url of a module block. Our choices are either to use the URL of the surrounding script/module, or to add a random fragment after it, but this fragment could not reliably be used to import the module block.

I think this issue does not block Stage 2, as it's in the scope of host environments. We should work out all of the details here by Stage 3, however.

@littledan littledan added this to the Stage 3 milestone Jan 11, 2021
@littledan littledan added the out of scope Feature requests which are out of scope for this proposal label Jan 11, 2021
@littledan littledan added host environment Questions to be answered in each host environment and removed out of scope Feature requests which are out of scope for this proposal labels Feb 4, 2021
@surma
Copy link
Member

surma commented Feb 25, 2021

From the Incubator Call: We should do some research of how import.meta.url is used in the wild right now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
host environment Questions to be answered in each host environment
Projects
None yet
Development

No branches or pull requests

4 participants