proposal-asset-references icon indicating copy to clipboard operation
proposal-asset-references copied to clipboard

Integration with import-maps proposal

Open just-boris opened this issue 7 years ago • 6 comments

Hello!

I am very happy to see, that the issues that developers find missing in the platform are being addressed.

But the proposed solution here is overlapping with another proposal: https://github.com/domenic/import-maps

import-maps introduce a new protocol import: that you can use to load any resources following the same path resolution algorithm, as you already have for JS modules. For example the image loading example from the readme of this proposal can be updated using import: protocol:

before

asset Logo from "./logo.gif";
async function loadLogo() {
  let img = document.createElement("img");
  img.src = URL.createObjectURL(Logo);
  return img;
}

after

async function loadLogo() {
  let img = document.createElement("img");
  img.src = 'import:./logo.gif'
  return img;
}

It would be nice, if these two proposals will be aligned with each other.

/cc @domenic

just-boris avatar Nov 22 '18 08:11 just-boris

@just-boris what exactly are you expecting to align?

https://github.com/sebmarkbage/ecmascript-asset-references#string-instead-of-assetreference-object has some notes on why a string isn't ideal for resources in this proposal.

bmeck avatar Nov 26 '18 15:11 bmeck

I opened this issue to make proposal authors aware about each other's work.

See the code examples above. There are two ways of doing the same thing, potentially. But if these two proposals would be developed in isolation, it might result in different behavior in terms how path resolution if woking. For example, would this proposal respect import-maps declaration in browser environment? What would happen if I will define asset Logo from "import:./logo.gif";?

just-boris avatar Nov 26 '18 16:11 just-boris

Although relative import: URLs probably won't work out (see https://github.com/domenic/import-maps/issues/75), in browsers we are more likely to use import.meta.resolve(). My latest thinking is that it could return a Request or a promise for a Response; see https://github.com/domenic/import-maps/issues/79. That is strictly more useful than the opaque asset references proposed here.

domenic avatar Nov 26 '18 20:11 domenic

@just-boris this proposal is not mandating any resolution behavior on hosts. A host could intercept the specifier and do anything it wants with it.

@domenic I think both those types have their own problems:

  • Request - to my knowledge is not a repeatable data type. multiple fetch() calls using it would have body consumption problems unless .clone() is used repeatedly. Also, these don't necessarily contain all the extra meta-data that one might wish to specify when performing any individual operation such as method. I'm not even sure how Request would map to all non-HTTP based environments such as filesystem using ones.
  • Promise<Response> - this means that the result type of operations is not synchronously available. So you would have to await any intermediate forms when chaining operations to locate resources. This seems like extraneous waste. In addition, since one of the driving factors for this proposal is to allow lazy acquisition of resources, this would need to be a lazy promise which is contrary to the general usage of Promise today.

For both of these types, I'm unclear on how they apply to the use case of lazily allowing import(foo) where foo comes from a different location potentially unless we handle them specially when passed into JS hooks. Currently they perform toString operations when passed to import() which seems less than ideal and we would need to stop doing for these types at least.

bmeck avatar Nov 26 '18 20:11 bmeck

to my knowledge is not a repeatable data type.

It is; you use clone(), or you just use GET requests which don't need cloning.

Also, these don't necessarily contain all the extra meta-data that one might wish to specify when performing any individual operation such as method.

This is not correct.

I'm not even sure how Request would map to all non-HTTP based environments such as filesystem using ones.

That's true; if those environments want to be compatible with browsers they might need to figure something out. Alternately those environments could just run the compatible subset of code produced by people which treat the requests as opaque.

this means that the result type of operations is not synchronously available

That is also true of opaque tokens. In the opaque token case, it's not only not synchronously available, it's just never available, period!

In addition, since one of the driving factors for this proposal is to allow lazy acquisition of resources, this would need to be a lazy promise which is contrary to the general usage of Promise today.

That's a pretty solid argument for Request instead of Promise<Response>, thanks!

I'm unclear on how they apply to the use case of lazily allowing import(foo) where foo comes from a different location potentially unless we handle them specially when passed into JS hooks.

I have a hard time understanding this paragraph, but from what I can tell it will always be redundant to do import(import.meta.resolve(foo)); you can just do import(foo) instead. So that use case is already handled by the language as-is.

domenic avatar Nov 26 '18 20:11 domenic

This is not correct.

I'm not sure how to respond to that, you even mention needing to use .clone else being stuck with GET methods. It also is mutable, so passing it around has similar problems to passing URL objects around.

That's true; if those environments want to be compatible with browsers they might need to figure something out. Alternately those environments could just run the compatible subset of code produced by people which treat the requests as opaque.

Unless this is going through WHATWG instead of ECMA I would assume it to be host agnostic. It could be left to host defined types though as well.

That is also true of opaque tokens. In the opaque token case, it's not only not synchronously available, it's just never available, period!

Opaque tokens are synchronously available as a reference identity. I don't understand the statement that it is not available? Do you mean it doesn't expose reflection? I could imagine it exposing reflection APIs if there are needs for them.

I have a hard time understanding this paragraph, but from what I can tell it will always be redundant to do import(import.meta.resolve(foo)); you can just do import(foo) instead. So that use case is already handled by the language as-is.

For relative locations this is more apparent:

import(resolve('./en.json', foo))

We want to be sure we never have to use await resolve() unnecessarily. In addition, we want to be sure that passing these around is somewhat safe to alleviate some workflows like React.lazy which are having to pass around a function to have a relative import() workflow that can be used by libraries.

bmeck avatar Nov 26 '18 20:11 bmeck