jamsinclair / jSquash

Browser & Web Worker focussed wasm bundles derived from the Squoosh App.
Apache License 2.0
222 stars 14 forks source link

Doesn't work in Vite SSR #34

Closed kanashimia closed 11 months ago

kanashimia commented 12 months ago

Describe the bug With Vite SSR first thing that you encounter is that you can't import jSquosh at all, it fails with:

node:internal/errors:496
    ErrorCaptureStackTrace(err);
    ^

Error: Cannot find module '/home/user/jSquash/examples/with-vite/node_modules/@jsquash/webp/codec/dec/webp_dec' imported from /home/user/jSquash/examples/with-vite/node_modules/@jsquash/webp/decode.js
    at new NodeError (node:internal/errors:405:5)
    at finalizeResolution (node:internal/modules/esm/resolve:224:11)
    at moduleResolve (node:internal/modules/esm/resolve:836:10)
    at defaultResolve (node:internal/modules/esm/resolve:1034:11)
    at ModuleLoader.defaultResolve (node:internal/modules/esm/loader:375:12)
    at ModuleLoader.resolve (node:internal/modules/esm/loader:344:25)
    at ModuleLoader.getModuleJob (node:internal/modules/esm/loader:220:38)
    at ModuleWrap.<anonymous> (node:internal/modules/esm/module_job:85:39)
    at link (node:internal/modules/esm/module_job:84:36) {
  url: URL {},
  code: 'ERR_MODULE_NOT_FOUND'
}

Importing using relative paths worked. optimizeDeps.exclude didn't help in any way.

OK, than with helpful suggestion of the people from the Astro chat I found that adding jSquash to ssr.noExternal fixed that.

But I couldn't fix the following: On Node 16 and Bun during decoding it fails with:

RuntimeError: Aborted(both async and sync fetching of the wasm failed). Build with -sASSERTIONS for more info.

On Node 20 it fails with:

TypeError: fetch failed
    at Object.fetch (node:internal/deps/undici/undici:11600:11) {
  cause: Error: not implemented... yet...
      at makeNetworkError (node:internal/deps/undici/undici:6911:35)
      at schemeFetch (node:internal/deps/undici/undici:11050:18)
      at node:internal/deps/undici/undici:10930:26
      at mainFetch (node:internal/deps/undici/undici:10947:11)
      at fetching (node:internal/deps/undici/undici:10904:7)
      at fetch2 (node:internal/deps/undici/undici:10782:20)
      at Object.fetch (node:internal/deps/undici/undici:11598:18)
      at fetch (node:internal/process/pre_execution:274:25)
      at instantiateAsync (/home/user/jSquash/examples/with-vite/node_modules/@jsquash/webp/codec/dec/webp_dec.js:8:8065)
      at createWasm (/home/user/jSquash/examples/with-vite/node_modules/@jsquash/webp/codec/dec/webp_dec.js:8:9070)
}

As I know Vite has knows problems with fetch during SSR, hence I tried importing it manually.

import webpDecode, { init as initWebpWasm } from "@jsquash/webp/decode";
const wasm = await readFile("./node_modules/@jsquash/webp/codec/dec/webp_dec.wasm");
await initWebpWasm(new WebAssembly.Module(wasm));
const webp = { decode: webpDecode };

(this code is also commented out in the stackblitz reproduction example)

But now there is this error: Node 20:

TypeError: Cannot read properties of undefined (reading 'bind')
    at /home/user/jSquash/examples/with-vite/node_modules/@jsquash/webp/codec/dec/webp_dec.js:8:30970
    at __emval_new (/home/user/jSquash/examples/with-vite/node_modules/@jsquash/webp/codec/dec/webp_dec.js:8:31249)
    at null.<anonymous> (wasm://wasm/00086ba2:1:122608)
    at null.<anonymous> (wasm://wasm/00086ba2:1:124983)
    at Object.decode (/home/user/jSquash/examples/with-vite/node_modules/@jsquash/webp/codec/dec/webp_dec.js:8:18298)
    at Object.decode (/home/user/jSquash/examples/with-vite/node_modules/@jsquash/webp/decode.js:23:27)
    at /home/user/jSquash/examples/with-vite/test.ts:13:13
    at ViteNodeRunner.runModule (file:///home/user/jSquash/examples/with-vite/node_modules/vite-node/dist/client.mjs:342:5)
    at ViteNodeRunner.directRequest (file:///home/user/jSquash/examples/with-vite/node_modules/vite-node/dist/client.mjs:326:5)
    at ViteNodeRunner.cachedRequest (file:///home/user/jSquash/examples/with-vite/node_modules/vite-node/dist/client.mjs:189:14)

Bun:

TypeError: undefined is not an object (evaluating 'constructor.bind')
      at WASM  ([wasm code])
      at WASM  ([wasm code])
      at processTicksAndRejections (:1:2602)

Vite doesn't support importing wasm same way as in the cloudflare worker examples, there is a plugin to fix that, but it doesn't work. Is my API usage valid at all?

To Reproduce Steps to reproduce the behavior:

  1. Try to use jSquash in vite-node environment
  2. ???
  3. Error

Reproduction URL https://stackblitz.com/edit/vitejs-vite-ndaywm?file=main.js

Module Versions Latest of them all

Additional context I was trying to create an image service for Astro, but was blocked by this. I found out that vite-node uses SSR too, hence it is used here for reproduction as it is much simpler than using framework framework framework. Just noting that it worked in Astro during astro dev, the problem there is with astro build.

jamsinclair commented 11 months ago

It looks like you're trying to use the library in Node.js and/or Bun. As noted in the library description and README – its intended usage is for the browser only.

Squoosh already provides a Node.js library if you'd like to use that, @squoosh/lib. There are also many other popular image focused libraries like sharp. Hopefully one of them works for your image service solution 🤞 , best of luck!!

kanashimia commented 11 months ago

None of those libraries really work for my use cases, hence why I was trying out your library, my intention was to get an image optimisation working on cloudflare pages with Astro SSR, there really seems like there is no single library that works. Well, I haven't really tried to actually run this library there, situation may be different, but would be nice to have one general solution. And squoosh is deprecated, by the name I thought that this library was a successor to squoosh or something. Better note explicitly that the library is not intended for use in node, it is not really clear from description.

jamsinclair commented 11 months ago

Thanks @kanashimia I appreciate the feedback, I want to confirm that it's not clear from the first few sentences of the library's README.

Other than explicitly stating "this is not for Node.js", I'm at a loss how much more clearer I can make it 😅

Screenshot 2023-09-30 at 1 19 00
kanashimia commented 11 months ago

My thoughts were somewhere along the lines of: >this library advertises for support in the Browser AND "V8 runtimes" >node uses V8 runtime >hmm, that was a weird way to word it, but should work >other bits are just about that it supports browser too >very cool, awesome library, works everywhere :)

jamsinclair commented 10 months ago

Seems like other users are confused too (#36), I'll make that more explicit. Thanks for the feedback and I hope you found a work around! 🤞