WICG / import-maps

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

Is URL mapping still necessary? #198

Closed guybedford closed 4 years ago

guybedford commented 4 years ago

The original argument for supporting mapping of URLs was to enable polyfill workflows where https://path/to/builtin-polyfill.js could be mapped to the builtin with a fallback.

The reason this was necessary was to support both browsers without import maps support and browsers with import maps support for builtin shimming.

With the newer timelines we are likely looking at import maps shipping quite a while before builtins ship, in which case this constraint no longer applies.

Since this constraint that initially pushed for URL mapping is no longer there, do we still need to support URL mapping?

The alternative is to just support bare specifiers in import maps.

Personally I prefer this for consistency of resolution and in knowing that eg import(await import.meta.resolve('pkg')) is always well-defined, instead of possibly resolving differently to import 'pkg'.

jkrems commented 4 years ago

With the newer timelines we are likely looking at import maps shipping quite a while before builtins ship, in which case this constraint no longer applies.

I think this still applies to older browsers without import maps support though? E.g. import 'https://poly.fill'; will work in browsers with import support but no import map support. Using bare specifiers directly would fail. But that's definitely a future-looking statement for "when and if builtins appear".

đź‘Ť for making sure that combining import.meta.resolve('pkg')/import is safe. Given those conflicting design goals, I think I would favor "need to send special legacy build to browsers w/o import map support" over "using import.meta.resolve to pre-resolve a URL before import isn't safe".

domenic commented 4 years ago

Mapping URLs is necessary to support the use case at https://github.com/WICG/import-maps#mapping-away-hashes-in-script-filenames. Since that is the only remaining use case that is not just syntactic sugar, we're certainly not going to remove it, at least not while still considering implementations in browsers (as opposed to build tools).

I don't understand the issue with import(await import.meta.resolve('pkg')). Perhaps you could flesh out the example.

guybedford commented 4 years ago

Since that is the only remaining use case that is not just syntactic sugar, we're certainly not going to remove it, at least not while still considering implementations in browsers (as opposed to build tools).

Hashing use cases are still being solved by import maps without URL mappings, but just at the package resolution hashing level over per-module. Packages with disjoint entry points can even have their subpaths fully hashed and shared via subpath mappings.

Yes a shared utils library within the package then invalidates the whole package, which seems to be the remaining slice of the use case at that point. But I'm still not sure that on it's own is enough to justify an entire use case of changing the local resolution meaning of URLs in the browser?

I don't understand the issue with import(await import.meta.resolve('pkg')). Perhaps you could flesh out the example.

Consider eg:

{
  "imports": {
    "pkg": "https://site.com/pkg.js",
    "https://site.com/pkg.js": "https://site.com/pkg-mock.js"
  }
}

Where import.meta.resolve('pkg') resolves to https://site.com/pkg.js but import(await import.meta.resolve('pkg')) will load https://site.com/pkg-mock.js.

The avoidance of this mapping issue only works with (a) full idempotence in the mapping system (guaranteed by removing URL mapping support), or (b) ensuring resolution only applies once in the resolver.

Even if recursive mapping is considered, there is always a chance that for a resolution that does N steps, that an N + 1 step would be a different resolution. So this is not about recursive v non recursive either.

domenic commented 4 years ago

I see. I think that is a pretty big flaw in import.meta.resolve(), which means it may not be something we want to introduce onto the web.

guybedford commented 4 years ago

Well, we have not got consensus to land import.meta.resolve() in Node.js yet either, current plans are to ship any experimental implementation behind a flag.

domenic commented 4 years ago

But I'm still not sure that on it's own is enough to justify an entire use case of changing the local resolution meaning of URLs in the browser?

I don't know what this is referring to. Did you mean to write "import specifiers" instead of "URLs"?

guybedford commented 4 years ago

Did you mean to write "import specifiers" instead of "URLs"?

Yes, URL-like import specifiers is a better term.

domenic commented 4 years ago

OK. Then, I will restate that changing the meaning of URL-like import specifiers per the example I linked is the only non-syntactic sugar use case, and thus the only motivating factor for implementing import maps in browsers.

guybedford commented 4 years ago

OK. Then, I will restate that changing the meaning of URL-like import specifiers per the example I linked is the only non-syntactic sugar use case, and thus the only motivating factor for implementing import maps in browsers.

I agree this is a, if not the, primary motivator for import maps, but as per my comment, URL-like import specifiers are not a prerequisite to this feature.

An application can ship two versions of its source - one with bare specifiers for import maps, and one without for legacy browsers. The version with bare specifiers gets per-package / disjoint package subpath caching between builds in an application with regular releases. Most dependencies don't need to be re-downloaded on updates to the app. This gets the 90% benefit.

As discussed, yes this loses within package hashing.

dcleao commented 4 years ago

As far as I understand, the main use case for import maps in the browser is the use of a virtual name instead of a URL for referring to modules, especially when combined with contextual mapping, thus supporting addressing to modules of multiple versions of a package, in the same environment.

For modules which live within a versioned package, hashing provides no extra benefit over the package version, for what caching is concerned. Unfortunately, during development of a package, a same version of a package is being mutated (edit: I mean that, during development, the package version is not changed, but still, the contained modules are). In this scenario, import specifiers would map to a hashed path, still at the package level. When only one module changes, the cache of all of a package's modules is lost.

But I'm not sure that this is a problem for development scenarios. First, as this most often happens on the local machine, the impact is not that bad. Second, possibly (and probably), development workflows don't take advantage of this form of mapping, due the use of hot-reloading techniques.

Can hot reloading be implemented on top of import maps, directly, with no additional "diff" protocol in place? I don't see how, at least until it becomes possible to "unload" a previously loaded module and to "load" it again. So, hot-reloading should continue being implemented using custom XHR techniques or the loading of sequential delta modules and a good amount of server-side code rewriting by tools.

Surely, modules can exist outside of a (versioned) package or be published in a URL which does not include the version. However, I believe that once "packages" land in the browser, in a "first-class" way, with the introduction of import maps, these will become the exception. Almost all resources consumed by a web page will live under versioned package folders. More so, web pages might even belong to the versioned package, and be published under an URL containing the package's version; in these cases, the URL is not seen/linked directly by the user.

This is how I imaging things going...

domenic commented 4 years ago

Let me close this, as it's starting to attract some rather confusing musings, and I have no plans of continuing to work on any version of the import maps spec that does not allow URL remapping.

dcleao commented 4 years ago

@domenic: you should learn to be polite to others. Writing «this is starting to attract some rather confusing musings», right after my previous comment, is very impolite, to my standards. And, I believe, to WICG standards, as well. It would be so even if you were referring also to others' older comments.

Unfortunately, this is not the first time that I observe a condescending and impolite behavior from you towards others' contributions, in this and other repositories in which you hold a position of authority. It is due to this being a recurrent observation that I cannot just swallow it anymore.

You justify closing the issue, in part, because you have no plans to "continuing to work on any version of the import maps spec that does not allow URL remapping", but I fail to see how that is a relevant reason. I believe that the value of this specification, in some form yet to be fully determined, is very big, and, in a way, independent of its sponsor. I believe it's more about the needs of the web platform and community; the community that is trying to help and be heard, by sharing its use cases and ideas with WICG.

I would much prefer that you would take the time to debate the content of my message, instead of dismissing it with what I consider being dubious, mocking and offending comments. Or, with the use of personal reasons or interest, for matters which can be debated very much objectively and are of the interest of many.

If it is not in WICG's interest, here represented by @domenic, to have to cooperate with the broader community in the development of these specifications, then, I, respectfully, ask WICG to take a transparent, closed and private approach, instead of — as I find — a far from open one.

/cc @marcoscaceres, @cwilso, @yoavweiss, @travisleithead

domenic commented 4 years ago

I apologize sincerely for offending you. It was not my intent to impugn on your words in any way, or to be mocking, offending, or dubious. I found them confusing, and did not understand their relationship to this issue (or indeed this repository), and as such I was not able to reply to their contents in any way. I wish I had communicated that more clearly than by using a single, easy-to-misinterpret word ("confusing").

I closed this issue because I did not see anything further to be discussed in terms of developing this specification, and unfortunately your latest reply does not seem to have clarified that. Regardless, I am extremely sorry for the distress I have caused you.

I welcome any chair help in smoothing over any interpersonal issues here, if you deem that necessary.

dcleao commented 4 years ago

Apologies taken. It's possible that English not being my native language makes me misinterpret your words and miss its subtleties.

dcleao commented 4 years ago

I found them confusing, and did not understand their relationship to this issue (or indeed this repository)

My words come in direct continuation to the conversation that was being had between you @guybedford. I was supporting his immediate reply to you, which said that:

URL-like import specifiers are not a prerequisite to this feature.

You were defending that URL-like specifiers are still needed for hashing and cache management and I went on trying to analyze the cases in which I believe hashing would still be used, if we were in a world where package-versioned files were consumed in the browser. I found these would be the majority.

My (implied) conclusion was that not supporting the per module hashing uses cases would be a minor problem, as I believe, again, was the conclusion stated by Guy in his previous message:

This gets the 90% benefit.

The connection of my comment with this thread (and to this repository) seems quite obvious. It's possible that my poor English, writing skills and somewhat confusing thought process have made you think that way.