kleisauke / wasm-vips

libvips for the browser and Node.js, compiled to WebAssembly with Emscripten.
https://kleisauke.github.io/wasm-vips/
MIT License
492 stars 25 forks source link

Errors with vite #58

Closed jlarmstrongiv closed 8 months ago

jlarmstrongiv commented 10 months ago

In dev mode

Failed to resolve entry for package "/Users/user/projects/astro-vips/node_modules/.vite/deps". The package may have incorrect main/module/exports specified in its package.json.
9:04:39 PM [vite] Internal server error: Failed to resolve entry for package "/Users/user/projects/astro-vips/node_modules/.vite/deps". The package may have incorrect main/module/exports specified in its package.json.
  Plugin: vite:asset-import-meta-url
  File: /Users/user/projects/astro-vips/node_modules/.vite/deps/wasm-vips.js?v=c3cd4bc3
      at packageEntryFailure (file:///Users/user/projects/astro-vips/node_modules/vite/dist/node/chunks/dep-bb8a8339.js:28725:11)
      at resolvePackageEntry (file:///Users/user/projects/astro-vips/node_modules/vite/dist/node/chunks/dep-bb8a8339.js:28722:5)
      at tryCleanFsResolve (file:///Users/user/projects/astro-vips/node_modules/vite/dist/node/chunks/dep-bb8a8339.js:28381:28)
      at tryFsResolve (file:///Users/user/projects/astro-vips/node_modules/vite/dist/node/chunks/dep-bb8a8339.js:28328:17)
      at TransformContext.transform (file:///Users/user/projects/astro-vips/node_modules/vite/dist/node/chunks/dep-bb8a8339.js:43235:32)
      at Object.transform (file:///Users/user/projects/astro-vips/node_modules/vite/dist/node/chunks/dep-bb8a8339.js:44352:62)
      at async loadAndTransform (file:///Users/user/projects/astro-vips/node_modules/vite/dist/node/chunks/dep-bb8a8339.js:55026:29)
      at async viteTransformMiddleware (file:///Users/user/projects/astro-vips/node_modules/vite/dist/node/chunks/dep-bb8a8339.js:64430:32)
09:07:28 PM [astro] Configuration updated. Restarting...

While dev mode starts to work with

optimizeDeps: {
    exclude: ["wasm-vips"],
},

This causes errors in build

vite v4.5.0 building for production...
transforming (11) node_modules/react/cjs/react-jsx-runtime.production.min.jsUnexpected early exit. This happens when Promises returned by plugins cannot resolve. Unfinished hook action(s) on exit:
(commonjs--resolver) resolveId "wasm-vips" "/Users/user/projects/astro-vips/src/components/VipsExample.tsx"
(vite:worker-import-meta-url) transform "/Users/user/projects/astro-vips/node_modules/wasm-vips/lib/vips-es6.js"
✓ 30 modules transformed.
✓ built in 526ms
file:///Users/user/projects/astro-vips/node_modules/rollup/dist/es/shared/node-entry.js:25902
                    reject(new Error(`Unexpected early exit. This happens when Promises returned by plugins cannot resolve. Unfinished hook action(s) on exit:\n` +
                           ^

Error: Unexpected early exit. This happens when Promises returned by plugins cannot resolve. Unfinished hook action(s) on exit:
(commonjs--resolver) resolveId "./vips-es6.js" "/Users/user/projects/astro-vips/node_modules/wasm-vips/lib/vips-es6.worker.js"
(vite:worker-import-meta-url) transform "/Users/user/projects/astro-vips/node_modules/wasm-vips/lib/vips-es6.js"
    at process.handleBeforeExit (file:///Users/user/projects/astro-vips/node_modules/rollup/dist/es/shared/node-entry.js:25902:28)
    at Object.onceWrapper (node:events:629:26)
    at process.emit (node:events:514:28) {
  code: 'PLUGIN_ERROR',
  plugin: 'commonjs--resolver',
  hook: 'resolveId',
  id: '/Users/user/projects/astro-vips/node_modules/wasm-vips/lib/vips-es6.js',
  watchFiles: [
    '\x00astro-entry:/Users/user/projects/astro-vips/src/components/VipsExample',
    '/Users/user/projects/astro-vips/node_modules/@astrojs/react/client.js',
    '/Users/user/projects/astro-vips/src/components/VipsExample.tsx',
    '/Users/user/projects/astro-vips/node_modules/react/index.js',
    '/Users/user/projects/astro-vips/node_modules/react-dom/client.js',
    '/Users/user/projects/astro-vips/node_modules/@astrojs/react/static-html.js',
    '/Users/user/projects/astro-vips/node_modules/react/cjs/react.production.min.js',
    '/Users/user/projects/astro-vips/node_modules/react-dom/index.js',
    '/Users/user/projects/astro-vips/package.json',
    '/Users/user/projects/astro-vips/node_modules/react/jsx-runtime.js',
    '/Users/user/projects/astro-vips/node_modules/wasm-vips/lib/vips-es6.js',
    '\x00commonjsHelpers.js',
    '\x00/Users/user/projects/astro-vips/node_modules/react/index.js?commonjs-module',
    '\x00/Users/user/projects/astro-vips/node_modules/react/cjs/react.production.min.js?commonjs-proxy',
    '\x00/Users/user/projects/astro-vips/node_modules/react/cjs/react.production.min.js?commonjs-exports',
    '/Users/user/projects/astro-vips/node_modules/react-dom/cjs/react-dom.production.min.js',
    '/Users/user/projects/astro-vips/node_modules/react/cjs/react-jsx-runtime.production.min.js',
    '/Users/user/projects/astro-vips/node_modules/scheduler/index.js',
    '\x00/Users/user/projects/astro-vips/node_modules/react/jsx-runtime.js?commonjs-module',
    '\x00/Users/user/projects/astro-vips/node_modules/react/cjs/react-jsx-runtime.production.min.js?commonjs-proxy',
    '\x00/Users/user/projects/astro-vips/node_modules/react/cjs/react-jsx-runtime.production.min.js?commonjs-exports',
    '\x00/Users/user/projects/astro-vips/node_modules/react/index.js?commonjs-proxy',
    '/Users/user/projects/astro-vips/node_modules/scheduler/cjs/scheduler.production.min.js',
    '\x00/Users/user/projects/astro-vips/node_modules/react-dom/client.js?commonjs-exports',
    '\x00/Users/user/projects/astro-vips/node_modules/react-dom/index.js?commonjs-proxy',
    '\x00/Users/user/projects/astro-vips/node_modules/react-dom/index.js?commonjs-module',
    '\x00/Users/user/projects/astro-vips/node_modules/react-dom/cjs/react-dom.production.min.js?commonjs-proxy',
    '\x00/Users/user/projects/astro-vips/node_modules/react-dom/cjs/react-dom.production.min.js?commonjs-exports',
    '\x00/Users/user/projects/astro-vips/node_modules/scheduler/index.js?commonjs-proxy',
    '\x00/Users/user/projects/astro-vips/node_modules/scheduler/index.js?commonjs-module',
    '\x00/Users/user/projects/astro-vips/node_modules/scheduler/cjs/scheduler.production.min.js?commonjs-proxy',
    '\x00/Users/user/projects/astro-vips/node_modules/scheduler/cjs/scheduler.production.min.js?commonjs-exports'
  ]
}

I would love to use wasm-vips, I just need to figure out how to import and use it

jlarmstrongiv commented 10 months ago

Here’s a reproducible example astro-vips.zip

jlarmstrongiv commented 10 months ago

I tried using vite with another popular wasm library ( https://www.npmjs.com/package/@sqlite.org/sqlite-wasm ) and it did build and bundle correctly with

optimizeDeps: {
    exclude: ["@sqlite.org/sqlite-wasm"],
},

Anyway, if you have suggestions on how to get wasm-vips working, please let me know!

EDIT: I’m going to try again tomorrow inside a plain astro component and see if that works any better

kleisauke commented 10 months ago

This is due to https://github.com/vitejs/vite/issues/7015. Fortunately, there's a workaround for this that seems to work:

Details `astro.config.mjs`: ```js import { defineConfig } from 'astro/config'; import react from '@astrojs/react'; // https://github.com/vitejs/vite/blob/ec7ee22cf15bed05a6c55693ecbac27cfd615118/packages/vite/src/node/plugins/workerImportMetaUrl.ts#L127-L128 const workerImportMetaUrlRE = /\bnew\s+(?:Worker|SharedWorker)\s*\(\s*(new\s+URL\s*\(\s*('[^']+'|"[^"]+"|`[^`]+`)\s*,\s*import\.meta\.url\s*\))/g // https://astro.build/config export default defineConfig({ integrations: [react()], server: { headers: { 'Cross-Origin-Embedder-Policy': 'require-corp', 'Cross-Origin-Opener-Policy': 'same-origin' }, }, vite: { build: { target: 'esnext', }, optimizeDeps: { esbuildOptions: { target: 'esnext' } }, worker: { format: 'es', // https://github.com/vitejs/vite/issues/7015 // https://github.com/vitejs/vite/issues/14499#issuecomment-1740267849 plugins: [ { name: 'Disable nested workers', enforce: 'pre', transform(code, id) { if (code.includes('new Worker') && code.includes('new URL') && code.includes('import.meta.url')) { return code.replace(workerImportMetaUrlRE, `((() => { throw new Error('Nested workers are disabled') })()`); } } } ] } } }); ```

However, this would mean that the locateFile handler on the incoming module would have to be overridden to provide support for nested workers, for example when using wasm-vips in a web worker (see: https://github.com/kleisauke/wasm-vips/issues/15#issuecomment-1110770951).

jlarmstrongiv commented 10 months ago

Thank you @kleisauke! Unfortunately, I’ve tried disabling the nested plugins, and it broke the dev server. It builds just fine though.

Can you describe:

cannot override the locateFile handler on the incoming module

I’m getting that Nested workers are disabled error.

I am using vips in a worker—is that allowed, or does vips spawn it’s own web worker?

Or is the way I’m importing the workers the problem?

// error
const vipsWorker = new Worker(
    new URL("../workers/vips.worker", import.meta.url),
    { type: "module", name: "comlink.worker" },
);

// error 
import vipsWorkerUrl from "../workers/vips.worker?worker&url";
const vipsWorker = new Worker(
    vipsWorkerUrl,
    { type: "module", name: "comlink.worker" },
);
image
import type { PluginOption } from "vite";

// https://github.com/vitejs/vite/blob/ec7ee22cf15bed05a6c55693ecbac27cfd615118/packages/vite/src/node/plugins/workerImportMetaUrl.ts#L127-L128
const workerImportMetaUrlRE =
  /\bnew\s+(?:Worker|SharedWorker)\s*\(\s*(new\s+URL\s*\(\s*('[^']+'|"[^"]+"|`[^`]+`)\s*,\s*import\.meta\.url\s*\))/g;

// https://github.com/vitejs/vite/issues/7015
// https://github.com/vitejs/vite/issues/14499#issuecomment-1740267849
export const disableNestedWorkers: PluginOption = {
  enforce: "pre",
  name: "Disable nested workers",
  transform(code) {
    if (
      code.includes("new Worker") &&
      code.includes("new URL") &&
      code.includes("import.meta.url")
    ) {
      return {
        code: code.replaceAll(
          workerImportMetaUrlRE,
          `((() => { throw new Error('Nested workers are disabled') })()`,
        ),
        // (Disable nested workers plugin) Sourcemap is likely to be incorrect: a plugin (Disable nested workers) was used to transform files, but didn't generate a sourcemap for the transformation. Consult the plugin documentation for help
        // - https://github.com/withastro/astro/pull/6817
        // - https://github.com/withastro/astro/pull/6817/files#diff-2daffa3917247b6251d31ca5525312790f033402a8d48d6616ec7dcf37b78ef6R86
        map: { mappings: "" },
      };
    }
  },
};
kleisauke commented 10 months ago

Apologies for the confusion; I mixed it up. You'll need to override the locateFile handler to support nested workers, I clarified my previous post.

I am using vips in a worker—is that allowed, or does vips spawn it’s own web worker?

Using wasm-vips in a worker is allowed. Given that Emscripten's pthreads integration also uses web workers, it can sometimes be tricky to set this up with different module bundlers, as you've noticed.

So, for example, if you initiate wasm-vips in a web worker and not overriding the locateFile handler, this happens:

graph TD
    A["vips-es6.js #40;bundled#41;"] -- "new Worker#40;new URL#40;'vips-es6.worker.js', import.meta.url#41;, {type: 'module'}#41;" --> vips-es6.worker.js
    vips-es6.worker.js --  "import#40;'./vips-es6.js'#41; " --> B["vips-es6.js #40;pre-processed#41;"]
     B["vips-es6.js #40;pre-processed#41;"] --> C["throw new Error#40;'Nested workers are disabled'#41;"]

But by overriding that handler, this happens:

graph TD
    A["vips-es6.js #40;bundled#41;"] -- "new Worker#40;locateFile#40;'vips-es6.worker.js'#41;, {type: 'module'}#41;" --> vips-es6.worker.js
    vips-es6.worker.js --  "import#40;'./vips-es6.js'#41; " --> B["vips-es6.js #40;pre-processed#41;"]
     B["vips-es6.js #40;pre-processed#41;"] -- "new Worker#40;locateFile#40;'vips-es6.worker.js'#41;, {type: 'module'}#41;" --> vips-es6.worker.js
jlarmstrongiv commented 10 months ago

I’m really sorry @kleisauke but do you have a full example using vips in a worker? I feel like I’m missing something important. Am I supposed to have a vips.js or vips-es6.js file? Do I import that from node_modules? What goes in it?

When using importScripts from the example, I get the error:

Uncaught TypeError: Failed to execute 'importScripts' on 'WorkerGlobalScope': Module scripts don't support importScripts().
    at vips.worker.ts:15:6

But, when I switch to classic, I get the error:

Uncaught SyntaxError: Cannot use import statement outside a module (at vips.worker.ts?type=module&worker_file:1:1)

And I need the workers to support ES Modules, so I feel like solving the first error is the way to go.

I also tried await import("./vips.js");, but get the error:

[vite] Internal server error: Failed to resolve import "./vips.js" from "../../core/src/astro/workers/vips.worker.ts?type=module&worker_file". Does the file exist?

Please note that I cannot use top-level await with comlink, so I put the await import("./vips.js"); inside the getVips function.

My worker file looks like:

/// <reference lib="webworker" />

import { expose } from "comlink";
import onetime from "onetime";
// import Vips from "wasm-vips";

// eslint-disable-next-line @typescript-eslint/consistent-type-imports
declare type VipsConstructor = typeof import("wasm-vips");

if (!(typeof importScripts === "function")) {
  // determine environment https://stackoverflow.com/a/23619712
  throw new TypeError(`[example.worker]: ENVIRONMENT_IS_WORKER is false`);
}

importScripts("./vips.js");

// libvips
// - https://www.npmjs.com/package/wasm-vips
// - https://wasm-vips.kleisauke.nl/playground/

const getVips = onetime(
  async () =>
    // @ts-expect-error Cannot find name 'Vips'.
    // eslint-disable-next-line @typescript-eslint/no-unsafe-call
    Vips({
      // @ts-expect-error Parameter 'fileName' implicitly has an 'any' type.
      locateFile: (fileName, scriptDirectory) =>
        `${scriptDirectory}${fileName}`,
      mainScriptUrlOrBlob: "./vips.js",
    }) as Promise<VipsConstructor>,
);

async function getImageUrl(): Promise<string> {
  const vips = await getVips();
  // #C83658 as CIELAB triple
  const start = [46.479, 58.976, 15.052];

  // #D8E74F as CIELAB triple
  const stop = [88.12, -23.952, 69.178];

  // Makes a lut which is a smooth gradient from start colour to stop colour,
  // with start and stop in CIELAB
  // let lut = vips.Image.identity() / 255;
  let lut = vips.Image.identity().divide(255);

  // lut = lut * stop + (1 - lut) * start;
  lut = lut.multiply(stop).add(lut.multiply(-1).add(1).multiply(start));

  lut = lut.colourspace(vips.Interpretation.srgb /* 'srgb' */, {
    source_space: vips.Interpretation.lab, // 'lab'
  });

  const buffer = await fetch("/assets/images/owl.jpg").then(async (resp) =>
    resp.arrayBuffer(),
  );

  let im = vips.Image.newFromBuffer(buffer);

  if (im.hasAlpha()) {
    // Separate alpha channel
    const withoutAlpha = im.extractBand(0, { n: im.bands - 1 });
    const alpha = im.extractBand(im.bands - 1);
    im = withoutAlpha
      .colourspace(vips.Interpretation.b_w /* 'b-w' */)
      .maplut(lut)
      .bandjoin(alpha);
  } else {
    im = im.colourspace(vips.Interpretation.b_w /* 'b-w' */).maplut(lut);
  }

  // Finally, write the result to a blob
  const t0 = performance.now();
  const outBuffer = im.writeToBuffer(".jpg");
  const t1 = performance.now();

  console.log(`Call to writeToBuffer took ${t1 - t0} milliseconds.`);

  const blob = new Blob([outBuffer], { type: "image/jpeg" });
  const blobURL = URL.createObjectURL(blob);

  return blobURL;
}

const workerInterface = {
  getImageUrl,
};

expose(workerInterface);

export type ExposedInterface = typeof workerInterface;

And I’m importing it in this Astro file:

---
// Usage
// <VipsWorker transition:persist />
---

<script>
  import { wrap } from "comlink";
  import type { ExposedInterface } from "../workers/vips.worker";
  import vipsWorkerUrl from "../workers/vips.worker?worker&url";

  // use newer syntax https://v3.vitejs.dev/guide/features.html#import-with-constructors
  const vipsWorker = new Worker(
    // new URL("../workers/vips.worker", import.meta.url),
    vipsWorkerUrl,
    { type: "module", name: "comlink.worker" },
  );
  const vips = wrap<ExposedInterface>(vipsWorker);
  // @ts-expect-error Element implicitly has an 'any' type because type 'typeof globalThis' has no index signature.
  globalThis.vips = vips;
  console.log("vipsWorker", await vips.getImageUrl());
</script>
kleisauke commented 10 months ago

do you have a full example using vips in a worker?

Here's a full example of using wasm-vips in a ES6 web worker with vanilla JavaScript: https://github.com/kleisauke/wasm-vips/issues/15#issuecomment-1825631671.

I tried to fix your code example above, but it didn't work. I tried this patch:

Details ```diff --- a/src/workers/vips.worker.ts +++ b/src/workers/vips.worker.ts @@ -2,33 +2,18 @@ import { expose } from "comlink"; import onetime from "onetime"; -// import Vips from "wasm-vips"; - -// eslint-disable-next-line @typescript-eslint/consistent-type-imports -declare type VipsConstructor = typeof import("wasm-vips"); +import Vips from "wasm-vips"; if (!(typeof importScripts === "function")) { // determine environment https://stackoverflow.com/a/23619712 throw new TypeError(`[example.worker]: ENVIRONMENT_IS_WORKER is false`); } -importScripts("./vips.js"); - // libvips // - https://www.npmjs.com/package/wasm-vips // - https://wasm-vips.kleisauke.nl/playground/ -const getVips = onetime( - async () => - // @ts-expect-error Cannot find name 'Vips'. - // eslint-disable-next-line @typescript-eslint/no-unsafe-call - Vips({ - // @ts-expect-error Parameter 'fileName' implicitly has an 'any' type. - locateFile: (fileName, scriptDirectory) => - `${scriptDirectory}${fileName}`, - mainScriptUrlOrBlob: "./vips.js", - }) as Promise, -); +const getVips = onetime(async () => Vips()); async function getImageUrl(): Promise { const vips = await getVips(); ```

and modified the package.json to include:

  "overrides": {
    "astro": {
      "vite": "^5.0.2"
    }
  }

(this ensures issue https://github.com/vitejs/vite/issues/13367 is not masking issue https://github.com/vitejs/vite/issues/7015)

This will hang indefinitely during astro build, so it seems that the above mentioned workaround is not effective when wasm-vips was imported in a web worker.

There's not much I can do for this, please subscribe to https://github.com/vitejs/vite/issues/7015 for updates related to this.

jlarmstrongiv commented 10 months ago

Thank you for trying @kleisauke ! I really appreciate your help and recommendations trying to solve this bug. I’ve followed the issue and look forward to when I can try wasm-vips. If you find any workarounds, please let me know and I’ll give them a try.

kleisauke commented 10 months ago

Thinking about this further, you might be able to patch vips-es6.js in a similar way as the Vite plugin does. Here's a minimal working example: astro-vips.zip

Hope this helps.

jlarmstrongiv commented 10 months ago

Thanks @kleisauke! That worked 🎉 I had to find and fix a few paths for the monorepo, but after studying your example with Vips, cleanup, and patch-package, I was able to get it working 🎉 thank you so much for helping debug vite and providing those extremely helpful examples

jlarmstrongiv commented 10 months ago

Actually, @kleisauke, I spoke too soon. I am running into CORS errors, even with workaroundCors: true,

Access to script at 'https://typefoundriesdirect.dev/assets/vips-es6-b7b0be19.js' from origin 'null' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
jlarmstrongiv commented 10 months ago

I was able to get it to work with workaroundCors: true, and mainScriptUrlOrBlob: "https://cdn.jsdelivr.net/npm/wasm-vips@0.0.7/lib/vips-es6.js",, but I would love to be able to serve the file locally.

Is the cors error due to loading the worker as a blob, which causes the origin header to be set to null which breaks cors?

kleisauke commented 10 months ago

I am running into CORS errors, even with workaroundCors: true,

Unfortunately, workaroundCors: true is no-op for ES6 modules, see: https://github.com/kleisauke/wasm-vips/issues/12#issuecomment-1099401544.

Is the cors error due to loading the worker as a blob, which causes the origin header to be set to null which breaks cors?

I think this is indeed the issue. It seems that vips-es6.worker.js is being inlined since its size is smaller than 4 KiB. Fortunately, you could set build.assetsInlineLimit to 0 to disable inlining altogether.

--- a/astro.config.mjs
+++ b/astro.config.mjs
@@ -10,7 +10,8 @@ export default defineConfig({
   },
   vite: {
     build: {
-      target: 'esnext'
+      target: 'esnext',
+      assetsInlineLimit: 0
     },
     optimizeDeps: {
       esbuildOptions: {
jlarmstrongiv commented 10 months ago

@kleisauke disabling all asset inlining has a pretty big performance impact. Is there another way with vite.worker.rollupOptions.external or vite.build.rollupOptions.external?

jlarmstrongiv commented 10 months ago

I’ve tried some of those rollup options, but I haven’t quite gotten it to work 🤔

kleisauke commented 10 months ago

I couldn't get it work with those Rollup options either. Hopefully sometime in the future this can be controlled with the ?no-inline or ?inline=false query suffixes.

The only two options I can think of to fix this are:

jlarmstrongiv commented 10 months ago

You’re right, the easiest solution is that mainScriptUrlOrBlob as vips-es6.js needs to be loaded from the public directory or a cdn

swissspidy commented 9 months ago

@jlarmstrongiv Which solution did you end up finding? I'd love to check it out.

I'm currently trying to get wasm-vips to run in a worker as well, and while https://github.com/kleisauke/wasm-vips/issues/15#issuecomment-1110770951 and https://github.com/kleisauke/wasm-vips/issues/58#issuecomment-1822629048 are really helpful for trying to understand the problem better, I have yet to get it working on my project (see https://github.com/swissspidy/media-experiments/pull/260)

Might be special because I'm using @shopify/web-worker to load code in a blob worker. I need to load wasm-vips in there or from a CDN (using jsdelivr right now) as I otherwise don't have control to add CORS header.

Anyway, having more examples of wasm-vips in a web worker would be really helpful to me.

Edit: I got it working now! The solution was to load https://cdn.jsdelivr.net/npm/wasm-vips@0.0.7/lib/vips.worker.js into a blob and then in the locateFile callback return a blob URL for it.

jlarmstrongiv commented 9 months ago

@swissspidy I tried @shopify/web-worker and it didn’t work for me, presumably because of its webpack and babel dependencies

This library contains three parts that must be used together:

- The public API of the package provided by @shopify/web-worker
- A babel plugin provided by @shopify/web-worker/babel that identifies uses of createWorkerFactory that need to be processed
- A webpack plugin provided by @shopify/web-worker/webpack that outputs the worker as a dedicated chunk

Did you get it working with a vite-based project?

swissspidy commented 9 months ago

I‘m not using Vite unfortunately, just React in this case.

kleisauke commented 8 months ago

Commit https://github.com/vitejs/vite/commit/4d1342ebe0969cbcfc9c6d7fc5347f85df07df7f introduces a new callback functionality to build.assetsInlineLimit, enabling users to selectively opt-in or opt-out for inlining. This enhancement will be available in an upcoming version of Vite, alowing you to do this:

--- a/astro.config.mjs
+++ b/astro.config.mjs
@@ -10,7 +10,9 @@ export default defineConfig({
   },
   vite: {
     build: {
-      target: 'esnext'
+      target: 'esnext',
+      assetsInlineLimit: (filePath) =>
+        filePath.endsWith('.worker.js') ? false : undefined,
     },
     optimizeDeps: {
       esbuildOptions: {

I'll close this as "won't fix" for now, as there's not much I can do for this. Please subscribe to https://github.com/vitejs/vite/issues/7015 for updates related to this.

kleisauke commented 6 months ago

Issue https://github.com/vitejs/vite/issues/7015 is now fixed via PR https://github.com/vitejs/vite/pull/16103, which is included in Vite v5.1.6. This means that the previously mentioned workarounds are no longer needed. :tada:

Here's a minimal working example: astro-vips.zip

jlarmstrongiv commented 6 months ago

@kleisauke fantastic news 🎉 thank you so much for the update and example

jlarmstrongiv commented 6 months ago

@kleisauke it seems that the vite worker no longer works? It appears that vite is attempting to bundle @vite/client with overlay.ts, which fails to due the webworker not having a dom. Other workers like sqlite3 and resvg work fine. Any idea why wasm-vips would be breaking?

jlarmstrongiv commented 6 months ago

I tried the older workaround, but that doesn’t seem to work either. Did something change in vite?

I also tried the workaround in https://github.com/vitejs/vite/issues/9879, but those didn’t work either

kleisauke commented 6 months ago

@jlarmstrongiv This looks like a regression introduced in PR https://github.com/vitejs/vite/pull/15852, I recommend downgrading Vite to v5.1.7 for now.

$ npm install vite@5.1.7
jlarmstrongiv commented 6 months ago

Fixed in vite@5.2.8

pepijnolivier commented 2 months ago

Hey @jlarmstrongiv would you mind setting up an example repository using vite and wasm-vips ? I cannot get this to work.

jlarmstrongiv commented 2 months ago

@pepijnolivier the only thing missing from this example is upgrading all dependencies and adding this option to the config:

  vite: {
    optimizeDeps: {
      exclude: ["wasm-vips"],
    },
  },