I am trying to bundle my threejs project which uses DRACOLoader file. It creates web-worker in runtime with BLOB url. I tried webpack / rollup to give options to worker loader.
But no use. It worker is in separate file, it becomes easy to give options. Why is it DRACOLoader uses runtime approach to create worker? and How shall i bundle it?
Is your entire application running in a Web Worker? Or could you explain what you’re trying to do with webpack’s worker-loader?
DRACOLoader creates its own Web Workers so that decoding does not block the main thread. It may start multiple workers, to decode parts of a model in parallel. It’s fully compatible with bundlers, but I don’t know whether DRACOLoader itself can run inside of a Web Worker — it may not have all the Browser APIs it needs, e.g. to start other Web Workers, in that location.
I am not looking to run DRACOLoader in another worker.
I am just looking to bundle DRACOLoader and other js files.
I am able to bundle all other js files and am able to run successfully.
But, When I am bundling DRACOLoader with webpack, I am able to generate minified file but browser is not able to recognize the worker.
But it requires static .js file. In DRACOLoader, worker gets created runtime with BLOB url. I am not able to figure out how to give this option to webpack.
like @donmccurdy said, you dont bundle draco. bundlers give you a /public folder, it contains files and folders that you intent to ship statically. draco has to be in that folder. your gltf’s as well, unless you import them from the src folder, in which case the bundler adds them to the dist and gives you a url hash.
personally, instead of fetch requests i would also prefer imports or dynamic imports, including the loaders. then it wouldn’t be browser dependent but cross platform. but that’s just how it is.
@drcmda I bundling my threejs project in the same way that you mentioned above, although I am not using worker loader right now. While making the build I am successfully able to make it but while running the build I am facing some error due to the draco loader, below are the details
Here is my build folder, In which ‘draco’ is in static directory
you don’t need workerloader, draco creates a worker by code, this has nothing to do with the bundler.
but, why is /static in your /dist? this is unusual. the bundlers job is to copy the contents of the /public folder into the /dist order, but not the folder itself. please use vite if you’re using anything else. “npx create vite” will create a proper project structure for you with a public folder, copy the draco bins in there.
“./static/draco” is a local path, depending from where you call it it can fail. the absolute path would be “/static/draco”.
but ideally, if the bundler is set up corretcly, “./static/draco” should just be “/draco”. this is how it would be in vite.
alternatively,
const drac = new DRACOLoader()
const gltf = new GLTFLoader()
drac.setDecoderPath("https://www.gstatic.com/draco/versioned/decoders/1.5.5/")
gltf.setDRACOLoader(drac)
I am using webpack as a module bunder for my project and and there is a static folder in my root directory which behaves same as public folder in vite, so while making the build, webpack copies the static files from static folder present in root directory and copies it into the build static folder. So it is same like public folder in vite.
And for some personal reasons I don’t want to use vite for this project.
And I have cross checked the paths also, there is no issue with paths for draco.
But let say, there is some issue with file structuring and storing the ‘draco’ in static folder. But these issue should not come if i am using cdn link for draco right ? Like given below
But while running the build ‘index.html’ file it is giving the same issue as I mentioned above.
I think It is due to some web worker issue for draco loader.
js opening up a worker is all but common: URL.createObjectURL(new Blob([functionString])). the bundler doesn’t get involved. worker-loader exists so that you can have external workers as js modules which can import packages. this isn’t what DRACOLoader is using.
the crash seems to be here (inside the worker) which indicates that it didn’t insert the draco stuff, which probably means it’s not able to fetch/resolve the correct binaries.
the cdn link has to work, please also make sure you have latest threejs.
And for some personal reasons I don’t want to use vite for this project.
you’re most likely fighting against this bundler and the rules it has regarding static files. i wouldn’t know how to help. you normally have /public, drop /draco in there, address it as “/draco” and that’s it.
I am not able to figure out what is the issue, I don’t know what I am missing.
Also its difficult to understand the issue for you also without any reference, therefore I have created a git repository which can help you to reproduce the error.
Here’s the Repository Link to reproduce the error, I also added error description and steps to reproduce the error in the readme. Let me know If am missed something.
this is imo not a valid url. requests should be absolute, relative urls are for imports. in any normal setup it’s just “Fox-draco.gltf”, if you have configured webpack to handle this differently it brings us to another thing …
*.gltf refers to external files whose paths must be obvious to the loader. in your case the gltf for instance refers to “Fox-draco.bin”, so again, it will url-fetch “Fox-draco.bin”, not “/static/Fox-draco.bin” and surely not “…/static/Fox-draco.bin”. if your project is set up weird these fetches will fail, it has likely nothing to do with web workers it just can’t find the buffers and textures.
there is a method on the loader where you can set the root path, but i would suggest webpack is fixed instead. it is not normal that you address /static, the contents of /static should be copied into /dist
if you use a *.glb instead of a *.gltf, then it contains everything in one, with or without draco. less room for errors.
@drcmda
I am looking into the project structure I have setup with webpack, I will correct it the things If wrong.
But the issue is not coming only for the gltf (having bin file) but also for glb and single gltf (without bin file) also. The problem is only occurring for the models which are compressed with draco (inside blender) weather it is gltf(embedded texture), gltf (with bin) or glb.
Also I am fetching the draco from cdn link and in the devtools network panel I am able to see that draco and their wasm files are getting fetched.
One more thing I wanna mention that, I am uisng webpack obfuscator in the webpack, so today I was testing and I found that when I disable the webpack obfuscator and make build without any obfuscation it is running correctly without any draco issue, but when I make build with webpack obfuscation enabled then it is giving error.
It will be better If you will run and reproduce the error inside your machine from the repo (link) I have provided and try to experiment the things.
Hey @Anish_Kumar I am experiencing the same error, only when obfuscated.
Additional details I have found are:
I have had this working before. It seems with a previous version of dracodecoder which is not created from blob, like this:
At this point, I’m considering incrementally rolling back my “@react-three/drei” until something works.
Any luck further debugging this on your end?
*Edit
I got it to work by obfuscating only my src files. To do this, I used react-app-rewire to expose React’s webpack config, then using the JavaScript-Obfuscator web pack loader (not the plugin) and including only my src directory.
I’m still trying to figure out how to get source maps to point back to unobfuscated typescript, but this resolved the error in the service worker.
Incidentally, by not including the node_modules imports in the obfuscation, my bundle size shrank from 2700kb to 400kb.