reactjsvitereact-three-fibermindar

How to correctly import web workers with Vite


I’m trying to integrate MindAR.js into a Vite + React (r3f) project using workers, but I can't get it to work, in a similar way to react-three-mind. I think the problem is that some Vite configuration for web workers is missing that I don't know about.

Importing the ControllerWorker from mind-ar like this

import { Controller as ImageTargetController } from "mind-ar/src/image-target/controller";

results in this error:

✘ [ERROR] No matching export in "node_modules/mind-ar/src/image-target/controller.worker.js?worker&inline" for import "default"

    node_modules/mind-ar/src/image-target/controller.js:4:7:
      4 │ import ControllerWorker  from "./controller.worker.js?worker&inline";

mind-ar/src/image-target/controller.js:4:7 contains this line:

import ControllerWorker  from "./controller.worker.js?worker&inline";

Tried already to override the worker for Vite:

// ./workers/controller.worker.js
export default new Worker(
  new URL('mind-ar/src/image-target/controller.worker.js', import.meta.url),
  { type: 'module' }
);
// ./mindar-patched.js
import * as OriginalController from "mind-ar/src/image-target/controller";
import ControllerWorker from "./workers/controller.worker";

// Override workers
OriginalController.ControllerWorker = ControllerWorker;

export const Controller = OriginalController.Controller;

Also tried to add alias in vite.config.ts:

alias: {
      "mind-ar/src/image-target/controller.worker.js?worker&inline":
          path.resolve(__dirname, "src/workers/controller.worker.js")
    },

The import with the bundled version (vite build) seems to work, but is hard to debug:

import { Controller as ImageTargetController } from "mind-ar/dist/mindar-image.prod.js";

Dependencies:

// vite.config.ts
import path from "path"
import tailwindcss from "@tailwindcss/vite"
import react from "@vitejs/plugin-react"
import { defineConfig } from "vite"

export default defineConfig({
  plugins: [react(), tailwindcss()],
  resolve: {
    alias: {
      "@": path.resolve(__dirname, "./src")
    },
  },
})
// package.json
"dependencies": {
  "react": "^18.2.0",
  "react-dom": "^18.2.0",
  "mind-ar": "^1.2.5",
  "three": "0.150.1",
  "@react-three/fiber": "^8.15.12",
  "@react-three/drei": "9.88.3"
  // ...
},
"devDependencies": {
  "vite": "^5.4.19",
  "@vitejs/plugin-react": "^4.0.0",
  "vite-plugin-worker": "^1.0.5"
  // ...
}

Maybe the ?worker&inline (Webpack?) is not supported by vite?


Solution

  • I could avoid this problem by importing the bundled version from the /dist/ folder like this:

    import {MindARThree} from "mind-ar/dist/mindar-image-three.prod.js";
    

    and use it like this:

    const mindarThree = new MindARThree({
      container: document.body,
      imageTargetSrc: "./card.mind",
      renderer: gl,
      scene: scene,
      camera: camera,
    });