tc39 / proposal-import-attributes

Proposal for syntax to import ES modules with assertions
https://tc39.es/proposal-import-attributes/
Apache License 2.0
599 stars 26 forks source link

Semantics of this feature in HTML/the Web #24

Open littledan opened 5 years ago

littledan commented 5 years ago

Note: The semantics of this proposal on the Web would be standardized in WHATWG/HTML, not in this repository. This issue is purely for requirements-gathering/brainstorming.

The README has examples of using the type: module attribute, but the semantics of this are not really defined anywhere. I think there's been some confusion in the discussion in issues as different people make assumptions about different semantics. Here's how I am currently picturing that this would work on the Web/in HTML:

Any thoughts on this logic?

littledan commented 5 years ago

Note, the above talks about how integration with type: would work, but I'd imagine the same logic would apply with out-of-band data, the type indicated as part of the module specifier, or with a single piece of additional data rather than key/value pairs.

ljharb commented 5 years ago

An unrecognized type should be ignored, as if none was provided, for the same reasons an unrecognized attribute is ignored. If the env can’t load the module, it will fail later.

littledan commented 5 years ago

@ljharb In this thread, we're talking about one specific environment--the Web. Are you saying that, if the type is not recognized, the Web should require that the MIME type be JavaScript? I don't understand the motivation for this behavior.

ljharb commented 5 years ago

I’m saying that if explicit type info is provided but unrecognized, it should fall back to the mime type. Obviously if the mime type is unrecognized it should act as it does now.

littledan commented 5 years ago

Based on the discussion at https://github.com/w3c/webcomponents/issues/839 , my understanding is that Mozilla and WebKit don't find it acceptable to choose the module interpretation based on the MIME type, at least when choosing between JavaScript and JSON/CSS/HTML (though WebAssembly may provide a point of flexibility). Within this repository, I'd like to work within that assumption. I'd recommend following up on that W3C thread if you want to see if that constraint can be loosened.

ljharb commented 5 years ago

I think I’m not being clear :-)

I’m saying that an import with an inline unrecognized type should behave the same as an import without an inline unrecognized type. If that means the only type that can be imported without an inline type is javascript, that’s fine.

littledan commented 5 years ago

Let's centralize discussion of the handling of unrecognized types in https://github.com/littledan/proposal-module-attributes/issues/27 . I'd rather not repeat ourselves in several different threads!

xtuc commented 5 years ago

I think that on the web it's important to set the Accept header when fetching the resource. For example:

import u from "https://a.cf/sven.jpeg" as json

The developer is requesting from the server a file of type json. The host does that by sending an the corresponding Accept header.

dandclark commented 5 years ago

The module is then parsed and processed according to its MIME type (which may provide more detailed information than simply the type:). The type: is not used at this point--it simply provided an additional check before the parser was invoked.

If we want to allow overlapping MIME type sets, as discussed in #16 (image/foobar+json etc), then in this step it is the type attribute, rather than the MIME type, that is what must be used to determine what kind of module to instantiate, or else we're left with some ambiguity.

([the MIME type] may provide more detailed information than simply the type)

Could you elaborate on this a bit? For modules, I'm not sure what information could be gleaned from the MIME type other than which type of module we should instantiate.

littledan commented 5 years ago

Well, as @xtuc mentioned, if JS BinAst has a different MIME type, it may require different processing, even if it's also a JS module.

jfparadis commented 5 years ago

Is "script" the only tag that will needs this feature? In particular, does it make sense to loading images or templates (already supported via the template tag) using a script tag?

littledan commented 5 years ago

@jfparadis Could you say more about what you mean by that? I could imagine other sorts of attributes passed to other subresources (e.g., fetch options or integrity), and these could be passed through other tags (or out-of-band manifests).

Jack-Works commented 4 years ago

I'd like to expect the browser to send different Sec-Fetch-Dest header based on different type.

import css from './global.css' with { type: 'css' }

Browser send Sec-Fetch-Dest: style and Server can return this based on the header

body { color: red; }

import css from './global.css'

Browser send Sec-Fetch-Dest: script and Server can return this based on the header

const css = new CSSStyleSheet()
const hasImport = x.includes('@import')
if (hasImport) css.replace(x)
else css.replaceSync(x)
export default css
littledan commented 4 years ago

Can we agree that the HTML/Web semantics needs to be worked out by Stage 3, but that we have a rough outline for how type would work, enough to get us to Stage 2?

justinmchase commented 2 years ago

Why wouldn't the type be application/json? As in:

import u from "https://a.cf/sven.json" as application/json

or

import u from "https://a.cf/sven.json" assert { accept: 'application/json' }

Then you could just pass it as the accept verbatim? Are you going to map assert types to all mime types and all future mime types?