tc39 / proposal-module-expressions

https://tc39.es/proposal-module-expressions/
MIT License
437 stars 20 forks source link

Resolution context of module blocks #57

Open guybedford opened 2 years ago

guybedford commented 2 years ago

Module blocks define resolution to be relative to the definition module. But beyond that there is also the question of which context that resolution is happening in. The URL is only one resolution parameter of the parent - which also has other associations such as realm and loading context which determine the exact resolver implementation in play.

This is important to define as it affects performance and workflow questions like whether engines be able to eagerly / speculatively fetch and parse (not execute) module block definitions even before they have been imported, as well as eg whether they would share the parent import map or not.

ljharb commented 2 years ago

Since modules don't always have a URL - that's a browser thing, not a language thing - "relative" doesn't even have a meaning in 262. Are you asking about the HTML integration semantics for it?

Anything that can be locked down in 262 here would be ideal; I'm not clear on what that would be. Do you have any ideas?

guybedford commented 2 years ago

For example, strictly defining module blocks resolution to be equivalent to resolution within the definition module would effectively cause import map sharing across workers and enable speculative fetching / compilation. So yes, that's the question, how strictly to define this.

ljharb commented 2 years ago

That seems intuitive to me - that the module block is in the same "context" as the module it's defined in. I'm not sure what else would be intuitive besides "it has no context", which would likely break a lot of use cases.

mhofman commented 2 years ago

I'm not sure what makes the most sense. I'd expect a host to resolve a relative identifier using the definition context by default, but I imagine some scenarios would require the importing context to be able to override or enhance that resolution using its own import map / resolution hooks.

My understanding is that the linking phase should happen in the importing context, so I don't know how much speculative fetching makes sense anyway.

kriskowal commented 2 years ago

As @mhofman mentions, we should not assume that any two Workers have the same module map or resolution rules. The programmer is obliged to send a module block that the receiver can understand. If designed well, module blocks should generalize to the case of programs using module blocks to convey instructions between separate hosts.

guybedford commented 2 years ago

but I imagine some scenarios would require the importing context to be able to override or enhance that resolution using its own import map / resolution hooks.

Certainly target-context hookability could be seen to be useful, although in most cases its the top-level context that is the easier one to hook which is why passing the global import map could be more flexible in many ways in allowing that same global import map to work across contexts (show me an app where that is not the desired case?).

It does seem like something that could go one way or the other though, and that that decision can be made or not from ECMA-262, so that it would definitely be worthwhile to openly consider the benefits and concerns of both approaches. I wouldn't feel certain stating absolutely either way at this point either.