AR-js-org / AR.js

Image tracking, Location Based AR, Marker tracking. All on the Web.
MIT License
5.3k stars 909 forks source link

"Multiple instances of Three.js being imported." warning, when working with npm packages of three.js and AR.js in one project #504

Open FireDragonGameStudio opened 1 year ago

FireDragonGameStudio commented 1 year ago

Do you want to request a feature or report a bug? I want to report a bug, at least as far as I can tell.

What is the current behavior? When importing three.js and AR.js for Marker Tracking (via npm packages, a warning that "Multiple instances of Three.js being imported." when starting the project. I use Vite as a bundler, if that information helps.

MyScript.js

import * as THREE from "three";
import * as THREEx from "@ar-js-org/ar.js/three.js/build/ar-threex";

I checked the three.js samples, they seem to import the three.js min library. May this be related?

I'll attach my package.json content too. package.json

{
  "name": "three-js-first-try",
  "private": true,
  "version": "0.0.0",
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "preview": "vite preview"
  },
  "devDependencies": {
    "vite": "^3.2.3"
  },
  "dependencies": {
    "@ar-js-org/ar.js": "^3.4.3",
    "three": "^0.146.0"
  }
}

If the current behavior is a bug, please provide the steps to reproduce. I just created a new project and added the npm packages via npm i three and npm i @ar-js-org/ar.js. When using Vite as bundler, starting the project with npx vite and the web dev tools console will show the warning.

Please mention other relevant information such as the browser version, Operating System and Device Name Firefox, Chrome on their latest versions.

What is the expected behavior? No warning.

If this is a feature request, what is motivation or use case for changing the behavior? not a feature request

nickw1 commented 1 year ago

Does the warning go away if you remove three from the dependencies?

I have a feeling the issue might be that AR.js already has a three.js dependency, and the built AR.js bundle already contains a copy of three.js so you are importing two separate copies of three.js, at different versions.

If that doesn't help, @kalwalt might know more as he developed the packaging system for AR.js.

FireDragonGameStudio commented 1 year ago

This was my first thought too, but when I remove three.js I can't no longer create scenes, renderer, etc... e.g.: scene = new THREEx.Scene(); doesn't work.

nickw1 commented 1 year ago

If you keep the three import, but remove it from the dependencies, does it work?

FireDragonGameStudio commented 1 year ago

Nope, unfortunately not :(

nickw1 commented 1 year ago

Is this just with markers, does it work with location-based?

FireDragonGameStudio commented 1 year ago

The warning appears with location only too.

kalwalt commented 1 year ago

I had this issue in the past, but i don' t remember now how i solved, but i will look into It when i can.

FireDragonGameStudio commented 1 year ago

Thank you, will be greatly appreciated!

nickw1 commented 1 year ago

Will try and have a look at location, but no guarantees I'll be able to solve it. I guess it's something to do with the packaging process.

kalwalt commented 1 year ago

I have a feeling the issue might be that AR.js already has a three.js dependency, and the built AR.js bundle already contains a copy of three.js so you are importing two separate copies of three.js, at different versions.

Three is included as an external package in webpack https://github.com/AR-js-org/AR.js/blob/be7c9083df5a651c2ab978ddd7c1a33409c4d40b/webpack.config.js#L9-L22 it should prevent to create another instance.

Maybe add three to devDependencies in package.json? I have to admit i never used vite bundler so "i'm walking in the dark". @FireDragonGameStudio Can you share more infos on your vite setup or do you have a github repository to have a look or test?

kalwalt commented 1 year ago

Another thing: Can you try instead to import the whole THREE namespace with: import * as THREE from "three"; only the classes that you need ? example: import { Mesh } from "three";

FireDragonGameStudio commented 1 year ago

Thx for the swift response. I'm currently not at home, but I'll give it a shot as soon as I'm back. The repo for this is https://github.com/FireDragonGameStudio/ARIndoorNavigation-Threejs but the current state is not pushed yet. Will do that as soon as I'm home too and give you an update here :)

FireDragonGameStudio commented 1 year ago

Unfortunately none of the suggested solutions helped. Neither moving three to devDependencies, nor only importing the needed classes. Tried to remove three completely, so maybe the dependency is resolved, deleted node_modules + package-lock.json too, but no change after npm install. Is it generally possible to use the AR.js three version? Smth. like var scene = new THREEX.Scene();?

I already pushed the current state of the project without installed three npm package, so feel free to check it out and play around.

Will try to bundle with webpack tomorrow. I have a feeling that Vite is messing with me... Oo

kalwalt commented 1 year ago

Unfortunately none of the suggested solutions helped. Neither moving three to devDependencies, nor only importing the needed classes. Tried to remove three completely, so maybe the dependency is resolved, deleted node_modules + package-lock.json too, but no change after npm install. Is it generally possible to use the AR.js three version? Smth. like var scene = new THREEX.Scene();?

I already pushed the current state of the project without installed three npm package, so feel free to check it out and play around.

Will try to bundle with webpack tomorrow. I have a feeling that Vite is messing with me... Oo

I think it depends by the set up. I see that you specify in package.json https://github.com/FireDragonGameStudio/ARIndoorNavigation-Threejs/blob/a21badd7bbd2ef33512acf39ce849ec142a485ba/package.json#L5 "type": "module" what happens if you disable it and add three in the dependencies?

FireDragonGameStudio commented 1 year ago

The warning unfortunately still appears :/

nickw1 commented 1 year ago

I thought I recognised this warning, but had not given it priority as it didn't stop anything working.

To investigate this, I've prepared an absolute basic location-based three.js example here:

https://github.com/nickw1/arjs-three-basic/

This uses npm to install AR.js and webpack to build.

My observations seem similar to @FireDragonGameStudio:

@kalwalt does this help?

kalwalt commented 1 year ago

I thought I recognised this warning, but had not given it priority as it didn't stop anything working.

To investigate this, I've prepared an absolute basic location-based three.js example here:

https://github.com/nickw1/arjs-three-basic/

This uses npm to install AR.js and webpack to build.

My observations seem similar to @FireDragonGameStudio:

  • if I import THREEfrom three, I get the multiple instances warning.
  • if I don't import THREE, then hardly surprisingly, THREE is undefined.

@kalwalt does this help?

I can confirm this but i haven't a solution at the moment. Thank you @nickw1

Platform-Group commented 11 months ago

I'm getting the same issue but with aframe location-based. It's causing me to have multiple video streams I'm pretty sure. I'm in the process of moving over from a html file to vue and where my vue set-up gets this warning and also has a second video window, one from the video element and one from the canvas it seems? I believe it's due to both ar-js and aframe importing three.js. Screenshot from 2023-07-26 16-14-59

@kalwalt did you ever find a solution?

juanRabaa commented 10 months ago

I think this is related to the way the build is bundling the files. I made a test modifying the UMD config of the threex-location-only to be built as a ESM instead. It does eliminate the multiple instances, but it removes the possibility of adding the file to a project any other way than by importing it as a module.

Meanwhile, there is a workaround in webpack that worked for me. Setting an alias in your config for three to be converted into node_modules/three. It should be similar for other bundlers as well.

This is an answer from this post https://discourse.threejs.org/t/threejs-custom-lib-usage-generate-warning-multiple-instances-of-three-js-being-imported/35292/3

module.exports = {
    // ...
    resolve: {
         // ...
        alias: {
            three: path.resolve('./node_modules/three')
        },
        // ...
    },
    // ...
};
Platform-Group commented 10 months ago

Thanks Juan, shame that I've already given up on Vue and gone back to barebones html, css and js now