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

Ignoring query or hash #251

Closed
giltayar opened this issue Apr 14, 2021 · 10 comments
Closed

Ignoring query or hash #251

giltayar opened this issue Apr 14, 2021 · 10 comments

Comments

@giltayar
Copy link

Currently there is no way to specify that the query part of a url be ignored, e.g. given

{
  "imports": {
    "./relative-src.mjs": "./relative-dst.mjs"
  }
}

There is no way to specify that ./relative-src.mjs?x=4 or ./relative-src.mjs#x map to ./relative-dst.mjs (with or without the appropriate hash or query).

Why is this important? Currently, in Node.js (and, I'm also assuming, in the browser), query parameters and hash are used as "cache busters", and enable us to reload a module, even if it was already loaded by the runtime. You can see an example of this cache-busting in Node.js in this article: https://dev.to/giltayar/mock-all-you-want-supporting-es-modules-in-the-testdouble-js-mocking-library-3gh1

Unfortunately, if there is an import map, there is no way to implement this functionality because all query/hash "variations" cannot be added to the importmap (and even if it was possible, it is not something that we would want to do).

I see two ways to deal with it:

  1. Ignore the hash when searching for a specifier in the importmap, and if found, add the hash to the resolved outcome. This will work for Node.js, but if cache-busting is implemented in the browser using queries (hashes won't work), then that won't work.

  2. Add a feature to importmaps to enable wildcarding query or hashes.

Personally, I prefer option 1, as it does not entail radical changes to the spec, and intuitively makes sense to me, but of cours any option that enables us to do some kind of cache-busting is welcome.

@ljharb
Copy link

ljharb commented Apr 14, 2021

The nature of URLs should mean that all of those already automatically map to the same thing.

@domenic
Copy link
Collaborator

domenic commented Apr 14, 2021

On the web we don't distinguish between different parts of the URL. This is in fact why cache-busting of the sort you describe works; the browser sees them as two different URLs and thus does not reuse the cached entry. This treatment of different URLs as different is a foundational part of web infrastructure and not something import maps is going to go against.

Instead, you should update your import map when you update your URLs.

@giltayar
Copy link
Author

@domenic the problem is that I don't know what all those URLs are going to be, as the cache-busting mechanism can generate an infinite amount of them.

I believe we will need some kind of mechanism in the import map to define that. At the very least (as I said in proposal #1) that hashes should anyway be ignored, just like the browser ignores them when sending the path to the server. Doing that would solve the Node.js cache busting mechanisms being used in ESM loaders.

And it makes sense anyway to ignore the hash when resolving a URL, because while it is strictly part of the URL, it is a part of the URL that is NOT sent to the server.

@giltayar
Copy link
Author

The nature of URLs should mean that all of those already automatically map to the same thing.

@ljharb - exactly. And ee need a mechanism in the import maps to specify exactly that: that "all these" urls should resolve to the same target, no matter what is in the query parameters or hashes.

For hashes it comes naturally: resolving should ignore the hash. For query parameters it is more difficult as some kind of wildcarding mechanism needs to be set in place. Me? I'm OK with just changing the spec to have it ignore hashes.

@domenic
Copy link
Collaborator

domenic commented Apr 15, 2021

Your cache busting mechanisms which generate new URLs for your resources need to also update your import map.

@giltayar
Copy link
Author

Your cache busting mechanisms which generate new URLs for your resources need to also update your import map.

Which would be perfect, but that means there should be a mechanism for dynamically updating the import map.

@giltayar
Copy link
Author

Actually, that wouldn't work either, because the esm loader (in my case) doesn't understand that it's running under a source map and wouldn't understand how to update the import map.

@domenic
Copy link
Collaborator

domenic commented Apr 15, 2021

Which would be perfect, but that means there should be a mechanism for dynamically updating the import map.

There is: when you generate new files that need to be cache-busted, you generate a new .html file containing the import map.

Actually, that wouldn't work either, because the esm loader (in my case) doesn't understand that it's running under a source map and wouldn't understand how to update the import map.

That sounds like a good feature request for your tool!

@Jamesernator
Copy link

You could probably do what you want here if matching becomes possible:

// import-map.json
{
    "imports": {
        "./path/to/file.js": "./path/to/other.js",
        "./path/to/file.js?*": "./path/to/other.js?*",
        "./path/to/file.js#*": "./path/to/other.js#*"
    }
}

@domenic domenic closed this as completed Oct 14, 2021
@He110te4m
Copy link

When I use esm.sh, I add a query parameter to my path, like this:

import useSWRInfinite from "swr/infinite";
{
  "imports": {
    "swr/": "https://esm.sh/[email protected][email protected]/"
  }
}

I got the same warning. Is that normal?

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

No branches or pull requests

5 participants