# Embed media expression

**URL:** <https://es.discourse.group/t/embed-media-expression/1352>\
**Category:** 💡 Ideas\
**Created:** [May 25, 2022, 4:28pm UTC](https://es.discourse.group/t/embed-media-expression/1352 "2022-05-25T16:28:49Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Klaider](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/klaider/32/1447_2.png) [@Klaider](https://es.discourse.group/u/Klaider)\
**Post date:** [May 25, 2022, 4:28pm UTC](https://es.discourse.group/t/embed-media-expression/1352/1 "2022-05-25T16:28:49Z")

</div>

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)

```javascript
let x = embed './thing.txt' as 'text/plain';
typeof x; // 'string'

```

- Binary

```javascript
let y = embed './thing.bin' as 'application/octet-stream';
y.toString(); // '[object ArrayBuffer]'

```

- Plain text (omiting MIME type)

```javascript
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:

- In Rust, the [`std::include_str!`](https://doc.rust-lang.org/std/macro.include_str.html) (UTF-8) and [`std::include_bytes!`](https://doc.rust-lang.org/std/macro.include_bytes.html) macros.
- In ActionScript, the `[Embed]` metadata.

#### 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_.

---

<div class="post-metadata">

**Author:** ![ljharb](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/ljharb/32/8_2.png) [@ljharb](https://es.discourse.group/u/ljharb)\
**Post date:** [May 25, 2022, 4:46pm UTC](https://es.discourse.group/t/embed-media-expression/1352/2 "2022-05-25T16:46:10Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Klaider](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/klaider/32/1447_2.png) [@Klaider](https://es.discourse.group/u/Klaider)\
**Post date:** [May 25, 2022, 4:48pm UTC](https://es.discourse.group/t/embed-media-expression/1352/3 "2022-05-25T16:48:29Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![bergus](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/bergus/32/152_2.png) [@bergus](https://es.discourse.group/u/bergus)\
**Post date:** [May 25, 2022, 9:37pm UTC](https://es.discourse.group/t/embed-media-expression/1352/4 "2022-05-25T21:37:09Z")

</div>

> [@Klaider](#):
>
> 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

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](https://github.com/tc39/proposal-import-assertions), see [here](https://2ality.com/2021/01/import-assertions.html) or check [Chrome's json module support](https://v8.dev/features/import-assertions).

---

<div class="post-metadata">

**Author:** ![Klaider](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/klaider/32/1447_2.png) [@Klaider](https://es.discourse.group/u/Klaider)\
**Post date:** [May 25, 2022, 9:46pm UTC](https://es.discourse.group/t/embed-media-expression/1352/5 "2022-05-25T21:46:00Z")

</div>

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.
