tc39/proposal-source-phase-imports

Consider wider evaluator attribute possibilities

guybedford opened this issue · 5 comments

Currently the proposal is entirely justified around the Web Assembly use case.

Typically the MIME type for fetch schemes, or the file extension for file schemes is considered the authoritative interpretation of the module format.

The justification for "as" here is entirely based around wanting to interpret the same MIME in multiple ways.

  • Is this something specific to Web Assembly, or does it extend to other formats?
  • Would patterns like as "typescript" want to be encouraged?
  • For those constructing custom host loaders, would custom formats be encouraged? Or treating "as" as an override of the MIME be encouraged?

Fleshing out some of these use cases and considering what sort of ecosystem this spec is guiding in these other types of module format directions seems an important aspect of the proposal.

One possibility here is that when module blocks are specified, they enable opaque references to uninstantiated modules to be provided to eg worker boundaries.

Alongside module blocks it could be possible to specify an evaluator attribute to get the "module block instance" for an existing source text module. This could be an interesting feature to include in the explainer for this spec.

The import assertions proposal requires a string asserts "str" at first, but changed to the JSON object later.

Should this proposal also support the JSON object form? e.g. as { wasm: "instance" }

@Jack-Works see discussion in #6, as much as possible we want evaluator attributes to alter the "module representation in JS" not the "module instantiation interpretation".

It seems very very dangerous to allow a specifier to be "loaded" - for example, transpiled on the fly - since such transpilations are virtually never 1:1 nor necessarily deterministic.

Is this something specific to Web Assembly, or does it extend to other formats?

I have not come up with any other good formats this would be useful for. One far stretched, but maybe possible idea would be a as "worker" import for JS, that would return a class that can be instantiated to start a web worker with the referenced code (inspired by web dev tooling features like these: https://vitejs.dev/guide/features.html#web-workers).

Other idea would be importing a script as "block" (#7), returning a module block, so essentially allowing users to defer instantiation of a module to a later point.

Would patterns like as "typescript" want to be encouraged?

I don't think so. How and if an asset is parsed should be entirely dependent on host determined semantics surrounding the asset, without input from the eval attribute: on the web/Deno this is the mime type, while in Node this would be a file extension. In fact, the evaluator attribute would not be available during the "asset load" (assuming loading is split into "asset load" and "binding instantiation"). Parsing of the asset should already be able to happen during "asset load" (for example a streaming parse + compile of a WASM binary).

If a host wanted to support TypeScript as a first class language (with automatic transpilation), this transpilation should happen in the "asset load" based purely on mime type / file extension.

For those constructing custom host loaders, would custom formats be encouraged? Or treating "as" as an override of the MIME be encouraged?

As mentioned above, I don't think this can or should be used to override mime types, and thus parsing behavior. Doing so would mean that on the web eval attributes would also affect the need for a specific asset to be fetched with CORS, resulting in requiring multiple asset loads (fetches) for a single specifier. This proposal specifically avoids this.