WICG / import-maps

How to control the behavior of JavaScript imports
https://html.spec.whatwg.org/multipage/webappapis.html#import-maps
Other
2.66k stars 69 forks source link

Split into fetch-maps and import-maps? #211

Closed jakearchibald closed 4 years ago

jakearchibald commented 4 years ago

I liked the import: proposal, but making (for example) a CSS image go through an import map felt a little backwards.

Should import-maps be design solely to handle JS module names, whereas another proposal, fetch-maps would handle general URL mapping.

This means import-maps would be mostly used for bare modules (including the prefix feature). Whereas fetch-maps would handle the hash cascade issue. In fact, you could say that import-maps only work for bare modules.

If both an import map and a fetch map existed for a client, the import map would be consulted first, then the fetch map.

This would also remove the Remapping doesn't work for <script> gotcha.

domenic commented 4 years ago

I'm a little confused by this issue. Import maps are designed soley to handle JS module specifiers.

The issue of handling only bare JS module specifiers was discussed and rejected in https://github.com/WICG/import-maps/issues/198

jakearchibald commented 4 years ago

My favourite feature of import-maps is the ability to "map away hashes in script filenames", but this isn't just a problem for script, it's a problem for any resource that references other resources.

In previous versions, import maps proposed solving this using import: urls:

<script type="importmap">
{
  "imports": {
    "/some-script.js": "/some-script.abc123.js",
    "/some-styles.css": "/some-styles.def456.css",
    "/bg.png": "/bg.321cba.png"
  }
}
</script>
<script>import '/some-script.js';</script>
<link rel="stylesheet" href="import:/some-styles.css">

And the CSS:

html {
  background: url('import:/bg.png');
}

I like that this solves the problem, but it seems weird having CSS go via an import map for a background image.

It feels like a more generic "fetch-map" would be less indirection. That leaves import-maps to handle the JS specific stuff.

domenic commented 4 years ago

import: is no longer part of the proposal, to be clear.

JS is somewhat unique in the web ecosystem in having deep dependency trees, which makes the hashes-in-filenames problem so acute there. Although in theory there can be deep dependency trees of @imports in styles, we don't see that in practice.

jakearchibald commented 4 years ago

import: is no longer part of the proposal, to be clear.

Yeah, I'm just worried it might feel odd later when we realise we need to solve the same problem for non-JS things.

JS is somewhat unique in the web ecosystem in having deep dependency trees

Sure, but as soon as one of those deep JS resources references an image, font, style, whatever, you've invalidated the tree.

jakearchibald commented 4 years ago

import: is no longer part of the proposal, to be clear.

Yeah, I'm just worried it might feel odd later when we realise we need to solve the same problem for non-JS things.

JS is somewhat unique in the web ecosystem in having deep dependency trees

Sure, but as soon as one of those deep JS resources references an image, font, style, whatever, you've invalidated the tree.

jkrems commented 4 years ago

Sure, but as soon as one of those deep JS resources references an image, font, style, whatever, you've invalidated the tree.

One example of a potentially common JS-refs-CSS case would be lazy loaded components that may have to reference associated styles (assuming they don't inline all styles in the JavaScript). That's where the issue becomes roughly as big as for scripts.

developit commented 4 years ago

The decision to limit import maps to JS specifiers seems like it might have to change if imported CSS subresources participate in the module graph (via the module-attributes proposal). If they do, I would imagine folks would expect them to also be covered by import maps.

domenic commented 4 years ago

To be clear, any import statements or import() expressions use import specifiers, and would be impacted by import maps. It doesn't matter whether they're referencing JS or CSS or whatever. (Assuming non-JS module types ever become a real thing.)

sashafirsov commented 4 years ago

For some reason developers are focusing only on single side of imports, whether is JS module or css as here. In my reality I never seen cdn or release deployment comprise only few file types. In addition to binary JS, there are css and images of all kind/resolution, source maps and sources themselves, all kind of metadata... And when we talk about importmaps the dependencies of all types to me are the subject of coherent treatment by url mapping and dependency by import. Hence the talks specific to js modules applicable to any kind resources including non-module JS, images, etc. There is a separate thread on waterfall effect when more libs brought to page which make pre-loaded config huge. Treating types separately will increase meta size even more.

domenic commented 4 years ago

I'll close this as the discussion is starting to meander and this doesn't seem to bring any new points that weren't previously discussed and decided in #198.

guybedford commented 4 years ago

I liked the import: proposal, but making (for example) a CSS image go through an import map felt a little backwards.

@jakearchibald can you dig into this a bit more?

It does seem from this discussion that it would be useful to see import: moving forward for these use cases.

I'm not sure where the best place would be to continue with work on this though.... a direct HTML spec PR?

domenic commented 4 years ago

(I think generally it's good to try to gather interest for new proposals in a separate repository, issue, or WICG Discourse thread before proceeding directly to the pull request stage.)

bicknellr commented 4 years ago

w.r.t. import: + procedurally created stuff: IMO, it would be better to abandon fallbacks in this proposal, make import.meta.resolve synchronous, and tell people to interpolate import.meta.resolve(specifier string) with when they're building HTML strings (or JSX, etc.) from 'inside' a JS module. For other proposed module types (HTML, CSS), the module itself provides a clear path / clear relationship to the import map against which (something like) import: URLs in things created declaratively in module's source text could be resolved; as opposed to things created procedurally 'by' a JS module which won't have that clear context unless some pretty heavy magic is involved. (Where 'magic' here is roughly the "inspect the call stack" thing which I think this spec had at one point and was removed.)

jakearchibald commented 4 years ago

I've made a proposal at https://discourse.wicg.io/t/proposal-fetch-maps/4259