I’ve integrated the viewer into a JS/React project but I get the warning, “THREE.WARNING: Multiple instances of Three.js being imported” and I’m wondering why. I can see it’s correct because my element tree looks like this.
Common issue in the JavaScript ecosystem. Usually this can be avoided if library maintainers make the dependency (three.js in this case) a peerDependency, so that the devs using it have to install it manually, but also ensure that there’s only 1 specific version installed.
In this case, however, even if the viewer package would make three.js a peerDependency, there are other indirect depdendencies of the viewer that are still not gonna do that and so the problem isn’t resolved.
In such cases you’re supposed to configure your build tool (vite? rollup? webpack?) to dedupe this dependency to ensure that only 1 version is ever bundled.
Not sure about other build tools, but there is pretty much always some kind of config option with dealing with this issue.
Another way to approach this is to dedupe at the node_modules level. In this case it would not be your build tool, but your package manager (npm? yarn?) that needs configuring to avoid multiple instances. Maybe yarn dedupe three.js is enough, or maybe you need to use resolutions to force a specific version and then dedupe it with yarn dedupe.
The solutions I outlined should work - either node_modules level dedupe or dedupe in the final app bundle. With either of those correctly configured there just isn’t a way for three.js to run multiple instances.
Can you share your build config and your package.json? What package manager are you using?
Is it simply just because I’m using mapbox-gl in one div (left) which is using Three under the hood and now Speckle (right) which is doing the same? Screenshot attached below.
The overrides bit will force all installed packages to only use this one specific three.js version. This means that you will also have to manually update the version to the correct one that the viewer package expects, however (currently seems to be 0.140.2)
I understand. I did try your solutions and I would have to force all versions of Three to 0.140. But if I’m using other apps like Mapbox that also use Three and maybe a newer version of Three, won’t doing that potentially break things? In that case I guess this warning is okay…
@aidannewsome The warning strongly implies that you should not have multiple versions of three.js running. Not only because the library is massive and bundling it multiple times is gonna meaningfully impact your app’s performance, but also because it clearly relies on some kind of singleton state that must not be duplicated. Even the three.js docs state this:
So if you’re worried about breaking things, you’re much more likely to break things running multiple instances of three.js than forcing all of your dependencies to rely on the same version instead. I don’t think forcing them to do that should be an issue at all, and if it is - then you should evaluate whether you should stop using incompatible dependencies.
If you run npm ls three in your CLI its gonna tell you what all of the installed versions are. They’re probably very close to each other, in which case you can just take the latest one and force that. If they’re many versions apart, to the point where stuff is breaking, then clearly you’re not supposed to use these dependencies together.
I don’t think three needs to be nested, then again I haven’t used npm in a while so if it works (you can double check with npm ls three returning the same version for everything) it’s OK.
Thanks Fabians, and sorry again for all the trouble. I’m a newb. I forced the additional Three package I was using to 0.140.2 to match Speckle and it fixed the warning. I appreciate your help.