deno icon indicating copy to clipboard operation
deno copied to clipboard

Support `import foo from "./bar.txt" with { as: "bytes" }`

Open lucacasonato opened this issue 1 year ago • 4 comments

Would import the relevant file as a byte buffer (Uint8Array). Maybe also import foo from "./bar.txt" with { as: "text" }?

lucacasonato avatar Sep 02 '24 09:09 lucacasonato

The import as text could also be very useful for bundler plugins.

marvinhagemeister avatar Sep 02 '24 09:09 marvinhagemeister

Also see https://github.com/whatwg/html/issues/9444

lucacasonato avatar Sep 02 '24 09:09 lucacasonato

Would be super useful for deno compile apps (https://github.com/denoland/deno/issues/17994)

littledivy avatar Sep 02 '24 17:09 littledivy

Consider immutable ArrayBuffer and spelling import uint8array from 'octets.bin' with { type: 'bytes' } to line up with type: 'json': https://github.com/tc39/proposal-immutable-arraybuffer

kriskowal avatar Oct 18 '24 06:10 kriskowal

this feature is essential to what Im doing because Im trying to import some assets from a JSR package I published Im sure its important for most library and frameworks authors

maliknajjar avatar Dec 06 '24 01:12 maliknajjar

I would use this feature a ton for app distribution in smallweb.

pomdtr avatar Dec 06 '24 08:12 pomdtr

thanks to @lucacasonato for the suggested feature

for anyone who needs a temporary solution untill this feature is implemented. you can embed the content of the static files in a json file. and import it as a json like this

    const res = await import("./files.json", {
      with: {
        type: "json",
      },
    });
    const content = res.default;

and the content of the files.json file may look something like this

{
  "Counter.js": "content...",
  "NewCounter.js": "content...",
  "style.css": "content..."
}

you can even embedd binary files by converting its content to base64 string

its an ugly solution but this is what we have for now as library creators

maliknajjar avatar Dec 06 '24 17:12 maliknajjar

Another alternative (based on deno-embedder): https://jsr.io/@smallweb/embed

pomdtr avatar Dec 07 '24 16:12 pomdtr

Found a new way to reference static assets from a jsr package using the newly released jsr support in https://github.com/esm-dev/esm.sh

See https://jsr.io/@smallweb/excalidraw/0.9.0/pkg/server.ts#L56

Basically, if the package was imported from an url, the static assets are fetch from raw.esm.sh instead of being read them from the filesystem.

pomdtr avatar Jan 28 '25 12:01 pomdtr

just throwing my 2c in on this issue, I'd like to see us be able to tell jsr which assets to download and have those be written to a folder by deno. Imo this is the most ideal workflow. We already have plenty of ways to bundle assets in a way that we can read in memory (see the above message). The issue is that most workflows are tied to the filesystem already, so its an extra step to massage in memory asset data back into something that can be used by the system. For instance, if I have a local web application that has asset data (like I do with jsr.io/@forager/web) then I need to add a build step to bundle those into something I can import into typescript, then massage those back into files, and then store those files on disk somewhere so that my application serve those, all during startup. This requires both --read and --write permissions, and likely --allow-env permissions as well to find a good directory to cache files. Imo, the most ideal situation is if deno can handle downloading asset files somewhere, and then we can see the filepath/folder for those assets. Something like:

{
{
  "name": "@forager/web",
  "version": "0.0.13",

  "exports": {
    ".": "./mod.ts",
    "./config": "./config.ts"
  },

  "publish": {
    "include": [
      "README.md",
      "LICENSE",
      "mod.ts",
      "config.ts",
      "server.js",
      {"files": "static/**/*", "download": true},
      {"files": "server/**/*", "download": true}
    ]
  }
}
}

which can then be referenced in code:

// mod.ts
import * as path from '@std/path'

const static_assets = path.join(import.meta.dirname, 'static')
const bundled_js = path.join(import.meta.dirname, 'server')
// now we can tell the server to serve files from these folders

andykais avatar Mar 12 '25 16:03 andykais

It'd probably be worth deprecating Deno.readFile[Sync] and Deno.readTextFile[Sync] in favour of these new approaches at some point, once implemented.

iuioiua avatar Apr 15 '25 23:04 iuioiua

Importing a binary blob is not a replacement for reading a file from disk - imports stay in memory forever, if you wish to load a file, process it and then reclaim the memory imports will not work for this use case.

bartlomieju avatar Apr 16 '25 08:04 bartlomieju

Oh... Didn't consider that.

iuioiua avatar Apr 16 '25 08:04 iuioiua

jsr will need to provide a way to export assets too... https://github.com/jsr-io/jsr/issues/987

jollytoad avatar Apr 22 '25 09:04 jollytoad

This feature is also important for writing WGSL shaders.

Is there any PR working on this yet?

xbwwj avatar May 21 '25 08:05 xbwwj

This feature is also important for writing WGSL shaders.

Is there any PR working on this yet?

here we can probably see some cause and effect https://github.com/denoland/deno_core/pull/1025

jerry4718 avatar Jun 21 '25 17:06 jerry4718

Are you planning on adding support for this to JSR?

KnorpelSenf avatar Nov 22 '25 10:11 KnorpelSenf

@KnorpelSenf yes, once https://github.com/tc39/proposal-import-bytes reaches later stages and we'll be sure that there will be no changes in semantics, we will stabilize it and add support for JSR.

bartlomieju avatar Nov 25 '25 12:11 bartlomieju

Amazing, thanks!

KnorpelSenf avatar Nov 25 '25 13:11 KnorpelSenf