Closed 7ombie closed 2 years ago
Maybe moving towards an API that's closer to the Response.Body
that fetch
resolves to would make sense:
import game from "mario.rom" assert {type: "arrayBuffer"};
Import assertions do not change what’s imported - they merely cause importing a module to throw, or not.
Import assertions do not change what’s imported - they merely cause importing a module to throw, or not.
@ljharb - Import assertions change how the code is imported. Without the assertion, the browser will try to execute the JSON text (as JavaScript code). This will be extended when Wasm support is implemented.
How would you import the source code from a GLSL file within the current spec?
@7ombie that's not correct. the browser doesn't evaluate the module at all when it's JSON and there's no assertion, but whenever it is evaluated, it is evaluated the same. (it may help to know that import assertions for JSON modules are also not required by the spec; the intention was always for non-browsers to not require the assertion when importing JSON)
@7ombie In your examples, what is the value of the imported thing? Like in import game from "mario.rom" assert {type: "arrayBuffer"}
, I assume game
would be an ArrayBuffer
?
In that sense I think this is more like CSS modules, which are part of the HTML spec. If you look at https://web.dev/css-module-scripts/, code like import sheet from './styles.css' assert { type: 'css' }
creates a sheet
variable of type CSSStyleSheet
. But it’s not the assertion that causes the browser to treat the import as CSS; it’s the MIME type of the network request, which in this case needs to be text/css
. The request fails unless both the MIME type and assertion are present and correct; the assertion is just a check that the MIME type of the resource is what the importing script expects.
TC39 has chosen to stay out of the business of defining available module types and their accompanying import assertions. You can see in https://html.spec.whatwg.org/multipage/webappapis.html#creating-scripts that the HTML spec has defined types for JavaScript (the default), JSON and CSS (see https://html.spec.whatwg.org/multipage/webappapis.html#creating-a-css-module-script). The types defined here are the standard that browsers follow, and have become the de facto standard that Node and Deno have also chosen to follow.
You can open an issue or PR at https://github.com/whatwg/html to suggest a new type. I would suggest you propose a “data” type with an assertion of "type": "data"
and a MIME type of application/octet-stream
. I would guess that this would be more likely to be accepted than anything particular to WebGL shaders.
@GeoffreyBooth - Thank you for the detailed reply. Much appreciated.
It's become pretty confusing what I'm even asking for, and my original post wasn't especially clear, so I wanted to explain in terms of how things currently work, as I understand it, and you can tell me what I'm getting wrong...
When a type assertion is added to an import, the string that defines the type is not specifying a MIME type. It's specifying an abstract import type.
Each import type has one or more associated MIME types, but also specifies other things, like if and how the file should be parsed and executed, which data types will be imported into the module, and under what circumstances et cetera.
The scope is strictly limited to specific import types that will likely expand to eventually include HTML, JavaScript, CSS, JSON and Wasm. I'm saying that we should also support more generic import types that would work with text files and binary data.
The more generic import types could just be text
and data
, with the data types String
and ArrayBuffer
, but that may be a little simplistic. Having import types that imply a text encoding or different data type (like Blob
) may be required/desired.
I admit I haven't given this much thought. I had a problem with importing some GLSL source (and didn't want my library to become asynchronous just so it can access it own source code), so ended up here. Just leaving a complaint seemed unhelpful, so went with suggesting something as a starting point. Ultimately, I just want to statically import text and data from files.
I wanted to explain in terms of how things currently work, as I understand it, and you can tell me what I’m getting wrong…
Import assertions are only a validation step. They don’t tell the browser how to interpret an import. The MIME type as listed in the Content-Type
header defines what a module’s type is. The assertion duplicates this information for the purposes of security. The idea is that an import
of JSON, say, shouldn’t turn into JavaScript—and be executed—when the importing script was expecting JSON data. The assertion type isn’t the same as the MIME type; json
is for application/json
and css
is for text/css
, for example.
This proposal, and the TC39 spec, define import assertions in the abstract—the assert
syntax itself, not which types can be asserted. The types are host-dependent, and therefore are defined in the HTML spec for browsers. (There’s no separate spec covering server-side runtimes like Node and Deno, so they follow the HTML spec for this.) Since WebGL is obviously browser-specific, I think the HTML spec is the place to open an issue. They can guide you through whether the best approach is data
or ArrayBuffer
or blob
or text
or whatever.
Thank you, @GeoffreyBooth. You're a legend. Thanks for the work you do on CoffeeScript too (I used to hang out there, as @carlsmith).
I get it now (finally). I'd conflated various standards processes, and just assumed this repo aught to get to the right folks. Sorry. That was ignorant of me. Thank you for your patience. Much appreciated.
Great, happy to help!
I'd like to import a WebGL frag shader into an ES6 module, and (because it's far easier to maintain) I'd also like to keep the shader source in its own GLSL file. There's currently no way to do this.
The supported alternatives are not very workable: Storing source code in a JSON string requires a lot of escaping, making the code effectively uneditable. Storing code in a multiline JS string, and exporting it from an ES6 module requires less escaping, but it's still pretty clunky.
Storing code in a proper source file with its conventional extension has a bunch of benefits that I don't need to list here, but there's no way to access those files (statically). Something like this would be useful:
While GLSL is a good usecase for a feature request, as it's a web standard, there are lots of less obvious usecases for importing source code and the bodies of other kinds of text file. None are very common, but there would be all kinds of useful corner-cases that this feature would address.
It would also be nice if we could import binaries into an
ArrayBuffer
too. Something like this:The same data could be stored in a JSON array, but it's a lot less efficient, and there are obvious advantages to storing binary data in its proper file format.