WICG / import-maps

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

Allow collapsing to a bundle using the hash symbol #185

Closed bahrus closed 4 years ago

bahrus commented 4 years ago

This is essentially a duplicate of https://github.com/WICG/import-maps/issues/145 and https://github.com/WICG/import-maps/issues/56 . With the latter one (issue 56) it was mentioned that, essentially, supporting bundled files is not part of import-maps, but will part of the package proposal. But it seems it will take quite a while for the package proposal to come to fruition, and in the meantime, we cannot effectively utilize CDN bundles without creating a massive JSON mapping. See my issue above for why I think supporting CDN bundles would be quite useful.

So I thought I came up with a clever hack to get some earlier support for this much needed requirement, but it doesn't work, and I want to make sure there's a good reason why it doesn't.

I have a reference to two files in my source JS:

import  "@ui5/webcomponents/dist/Input.js";
import "@ui5/webcomponents/dist/TextArea.js";

In my import mapping, I created this:

    <script type="importmap">
    {
        "imports": {
            "@ui5/": "https://storage.googleapis.com/pika-web-packages-02/ui5-buffet/0.0.0/dist-es2019/ui5-buffet.min.js#/"
        }
   }

Here's my (apparently naive) thinking: based on the mapping, the import for Input.js should resolve to:

https://storage.googleapis.com/pika-web-packages-02/ui5-buffet/0.0.0/dist-es2019/ui5-buffet.min.js#/webcomponents/dist/Input.js

And the import for TextArea should resolve to:

https://storage.googleapis.com/pika-web-packages-02/ui5-buffet/0.0.0/dist-es2019/ui5-buffet.min.js#/webcomponents/dist/TextArea.js

But generally speaking, the part of the url after the hash symbol (#) isn't sent to the server, meaning both references would really be pointing to the same (bundled) file.

Instead, Chrome 77 seems to be dropping the last part of the url (ui5-buffet.min.js):

https://storage.googleapis.com/pika-web-packages-02/ui5-buffet/0.0.0/dist-es2019/webcomponents/dist/Input.js

Why? It seems like it is going out of its way to prevent having multiple files resolve to the same file, with a single line in the import map configuration.

hiroshige-g commented 4 years ago

Explanation of how it currently behaves

This is because https://wicg.github.io/import-maps/#resolve-an-imports-match Step 1.2.3 processes the match by parsing relative URLs (in spec and Chromium implementation):

Let url be the result of parsing afterPrefix relative to the base URL address.

i.e. new URL('webcomponents/dist/Input.js', 'https://storage.googleapis.com/pika-web-packages-02/ui5-buffet/0.0.0/dist-es2019/ui5-buffet.min.js#/').href => "https://storage.googleapis.com/pika-web-packages-02/ui5-buffet/0.0.0/dist-es2019/webcomponents/dist/Input.js"

not by concatenation:

new URL('https://storage.googleapis.com/pika-web-packages-02/ui5-buffet/0.0.0/dist-es2019/ui5-buffet.min.js#/' + 'webcomponents/dist/Input.js').href => "https://storage.googleapis.com/pika-web-packages-02/ui5-buffet/0.0.0/dist-es2019/ui5- buffet.min.js#/webcomponents/dist/Input.js"

The behavior has been changed mutiple times:

How should it work?

I slightly liked relative URL parsing because it's conceptually clean, making import maps less magical: the right hand side of import maps are always URLs, and we handle the RHS URLs as URLs, not serialize+concat+parse again.

On the other hand, concatenation might be better for use cases like this issue or https://github.com/WICG/import-maps/issues/173#issuecomment-522716045.

Related: #166 #173

domenic commented 4 years ago

We're still not interested in taking on bundling use cases.