Embed media expression

I want something similiar to importing JSONs, but in case it's any file. For example, I want to be able to include plaintext or octet-stream without having the content parsed together with JavaScript source code.

I know that transpilers allow you to import assets (like import data from 'data.json'), but they end up clustering the final bundle with content parsed as code. Thus I suggest an embed expression, which would work everywhere (browser, Node etc.):

  • Plain text (UTF-8)
let x = embed './thing.txt' as 'text/plain';
typeof x; // 'string'
  • Binary
let y = embed './thing.bin' as 'application/octet-stream';
y.toString(); // '[object ArrayBuffer]'
  • Plain text (omiting MIME type)
let z = embed './thing.txt';
typeof z; // 'string'

embed would be a context keyword followed by a literal string. The other literal string is the MIME type. At least 'text/plain' and 'application/octet-stream' should be supported.

In other languages there is a similiar way of doing that:

FAQ

But can't you just use fetch, XHR (browser) or file system (Node) for this purpose? The idea is to be able to preload external resources regardless of environment (whether it's a browser or Node runtime). The idea is to also resolve resources from the relative path of a module (which is crucial for libraries).

But why if JavaScript does not have file system support? The idea is not to read file metadata or manipulate file, it's just to preload its contents.

There's no such thing as a "file" in the language - JS has no i/o whatsoever.

The suggestion isn't to add file system support to the language, it's just a basic preload of external data and media, for use with libraries mostly, but also fine with entry point code.

As you can see, the preload would result in either ArrayBuffer or string. ArrayBuffer is one of the global objects of JavaScript.

That's exactly what the Rust and ActionScript macros you linked do as well - embed the content in the compiled artifact.
However, I don't see why a transpiler couldn't also transpile that into a const data = await (await fetch('data.json')).json() if you prefer to do that. It doesn't really need new syntax I think.

If anything, this should piggyback off the import assertions proposal, see here or check Chrome's json module support.

Having this without proper syntax has the following drawback:

  • 'data.json' is resolved relative to the entry-point, not relative to the importee file path.
  • Code to preload the file is asynchronous.

Both of these drawbacks harm the use of certain libraries. For example, i18n libraries that store language information rely on merging data with the sources, since there's no other way to embed this information.