# Bundling threejs project with DRACOLoader (webworker)

**URL:** <https://discourse.threejs.org/t/bundling-threejs-project-with-dracoloader-webworker/17205>\
**Category:** Questions\
**Tags:** loaders\
**Created:** [July 18, 2020, 8:53am UTC](https://discourse.threejs.org/t/bundling-threejs-project-with-dracoloader-webworker/17205 "2020-07-18T08:53:29Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![TejaSwaroopArukoti](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/tejaswarooparukoti/32/12261_2.png) [@TejaSwaroopArukoti](https://discourse.threejs.org/u/TejaSwaroopArukoti)\
**Post date:** [July 18, 2020, 8:53am UTC](https://discourse.threejs.org/t/bundling-threejs-project-with-dracoloader-webworker/17205/1 "2020-07-18T08:53:30Z")

</div>

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.

[https://webpack.js.org/loaders/worker-loader/](https://webpack.js.org/loaders/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?

---

<div class="post-metadata">

**Author:** ![donmccurdy](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/donmccurdy/32/33209_2.png) [@donmccurdy](https://discourse.threejs.org/u/donmccurdy)\
**Post date:** [July 18, 2020, 4:54pm UTC](https://discourse.threejs.org/t/bundling-threejs-project-with-dracoloader-webworker/17205/2 "2020-07-18T16:54:28Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![TejaSwaroopArukoti](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/tejaswarooparukoti/32/12261_2.png) [@TejaSwaroopArukoti](https://discourse.threejs.org/u/TejaSwaroopArukoti)\
**Post date:** [July 19, 2020, 6:06am UTC](https://discourse.threejs.org/t/bundling-threejs-project-with-dracoloader-webworker/17205/3 "2020-07-19T06:06:47Z")

</div>

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.

For webpack to recognize the worker, I am using the below loader.  
[https://webpack.js.org/loaders/worker-loader/](https://webpack.js.org/loaders/worker-loader/).

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.

---

<div class="post-metadata">

**Author:** ![donmccurdy](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/donmccurdy/32/33209_2.png) [@donmccurdy](https://discourse.threejs.org/u/donmccurdy)\
**Post date:** [July 19, 2020, 6:20am UTC](https://discourse.threejs.org/t/bundling-threejs-project-with-dracoloader-webworker/17205/4 "2020-07-19T06:20:32Z")

</div>

The decoder path given to DRACOLoader needs to have statically hosted files - they cannot be bundled.

If you’re having trouble getting this to build you will need to share enough code to reproduce the issue you are having and the errors you see.

---

<div class="post-metadata">

**Author:** ![drcmda](https://avatars.discourse-cdn.com/v4/letter/d/91b2a8/32.png) [@drcmda](https://discourse.threejs.org/u/drcmda)\
**Post date:** [July 19, 2020, 8:42am UTC](https://discourse.threejs.org/t/bundling-threejs-project-with-dracoloader-webworker/17205/5 "2020-07-19T08:42:40Z")

</div>

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.

here’s a running example, it’s react but just look into `/public`, you’d do the same in plain three. [https://codesandbox.io/s/r3f-ibl-envmap-simple-y541h](https://codesandbox.io/s/r3f-ibl-envmap-simple-y541h)

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.

---

<div class="post-metadata">

**Author:** ![Anish\_Kumar](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/anish_kumar/32/39755_2.png) [@Anish\_Kumar](https://discourse.threejs.org/u/Anish_Kumar)\
**Post date:** [February 23, 2024, 6:49am UTC](https://discourse.threejs.org/t/bundling-threejs-project-with-dracoloader-webworker/17205/6 "2024-02-23T06:49:22Z")

</div>

hey @TejaSwaroopArukoti , did you found any solution for this, I am facing the same issue.

---

<div class="post-metadata">

**Author:** ![Anish\_Kumar](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/anish_kumar/32/39755_2.png) [@Anish\_Kumar](https://discourse.threejs.org/u/Anish_Kumar)\
**Post date:** [February 23, 2024, 7:05am UTC](https://discourse.threejs.org/t/bundling-threejs-project-with-dracoloader-webworker/17205/7 "2024-02-23T07:05:09Z")

</div>

@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

 ![image](https://canada1.discourse-cdn.com/flex035/uploads/threejs/original/3X/1/5/157579771e9e6e1f5d4e4911bd7a293b3c463214.png)

Here I am setting up the draco loader:

 ![image](https://canada1.discourse-cdn.com/flex035/uploads/threejs/original/3X/9/0/906eab34437ade704caccceb71705cbb8a4cc4a6.png)

Here Is the error I am facing while running ‘index.html’ file from build file (or dist)  
 ![image](https://canada1.discourse-cdn.com/flex035/uploads/threejs/original/3X/8/a/8a753332ce10d12ad84e453ff30728b8171f0f57.png)

![image](https://canada1.discourse-cdn.com/flex035/uploads/threejs/original/3X/3/a/3a2f987cc816e894f787e73e88daf04a9247bc07.png)

While running the project on webpack dev server it is running perfectly, but while running build file it is giving some “draco loader” issue.

Thanks

---

<div class="post-metadata">

**Author:** ![drcmda](https://avatars.discourse-cdn.com/v4/letter/d/91b2a8/32.png) [@drcmda](https://discourse.threejs.org/u/drcmda)\
**Post date:** [February 23, 2024, 7:53am UTC](https://discourse.threejs.org/t/bundling-threejs-project-with-dracoloader-webworker/17205/8 "2024-02-23T07:53:52Z")

</div>

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,

```jsx
const drac = new DRACOLoader()
const gltf = new GLTFLoader()
drac.setDecoderPath("https://www.gstatic.com/draco/versioned/decoders/1.5.5/")
gltf.setDRACOLoader(drac)

```

---

<div class="post-metadata">

**Author:** ![Anish\_Kumar](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/anish_kumar/32/39755_2.png) [@Anish\_Kumar](https://discourse.threejs.org/u/Anish_Kumar)\
**Post date:** [February 23, 2024, 8:37am UTC](https://discourse.threejs.org/t/bundling-threejs-project-with-dracoloader-webworker/17205/9 "2024-02-23T08:37:50Z")

</div>

Hey @drcmda thanks for your response,

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

```javascript
        this.dracoLoader = new DRACOLoader();

		// Setup Draco Loader
        this.dracoLoader.setDecoderPath("https://www.gstatic.com/draco/versioned/decoders/1.5.5/");
		this.gltfLoader.setDRACOLoader( this.dracoLoader );

```

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.

Let me know what you think about this

Thanks

---

<div class="post-metadata">

**Author:** ![drcmda](https://avatars.discourse-cdn.com/v4/letter/d/91b2a8/32.png) [@drcmda](https://discourse.threejs.org/u/drcmda)\
**Post date:** [February 23, 2024, 10:06am UTC](https://discourse.threejs.org/t/bundling-threejs-project-with-dracoloader-webworker/17205/10 "2024-02-23T10:06:05Z")

</div>

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](https://github.com/mrdoob/three.js/blob/841d2e791d3e8a2463322c5ca31b16956828b91c/examples/jsm/loaders/DRACOLoader.js#L416C3-L416C26) (inside the worker) which indicates that it didn’t [insert the draco stuff](https://github.com/mrdoob/three.js/blob/841d2e791d3e8a2463322c5ca31b16956828b91c/examples/jsm/loaders/DRACOLoader.js#L297-L308), 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.

---

<div class="post-metadata">

**Author:** ![donmccurdy](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/donmccurdy/32/33209_2.png) [@donmccurdy](https://discourse.threejs.org/u/donmccurdy)\
**Post date:** [February 23, 2024, 3:18pm UTC](https://discourse.threejs.org/t/bundling-threejs-project-with-dracoloader-webworker/17205/11 "2024-02-23T15:18:43Z")

</div>

Upvotes and kindly-explained use cases on this feature request would be welcome, I think:

> <https://github.com/google/draco/issues/977>
>
> Hi,
> 
> I'm a user of the draco3d library for glTF encoding/decoding - I am also …a contributor to the glTF standards. It is quite challenging to use this library in its current form. A few combined issues make it quite challenging:
> 
> \- The npm packages only supports node.js operation and has hard coded dependences on NodeJS-specific fs and path libraries as well as relying on \_\_dirname, which isn't available in ES modules.
> \- The npm packages rely upon CommonJS rather than more modern ES modules, thus you need to use old school bundlers.
> \- The browser version of the library isn't in any npm package, thus you have to copy it manually into projects.
> \- The browser version of the library also doesn't have typings (e.g. @types/draco is only for the node.js-specific npm module.)
> 
> Together this makes this library super old-school and a pain to use, even though it has awesome functionality.
> 
> The best way forward would be to:
> 
> \- update the npm package so that the decoder/encoder is not dependent upon either the browser or Node.JS, rather it is independent and just operates on ArrayBuffers.
> \- the npm package should be published in at minimum ES module format, and I guess you can keep the CommonJS. Use the "module" and "main" fields of the "package.json" respectively for this dual publishing method.
> \- There is a function on the main wrapper in which you can pass in the WASM file. So you can load it differently depending on the platform, but once loaded you initialize it into the library the same way.
> 
> Relying upon primarily the emscripten version would allow one to just package this up so that anyone can use it. Trying to load the WASM module makes things a lot more complex because import support for WASM nor bundler support for WASM is here yet.
> 
> This would allow something like this in Node.js:
> 
> \`\`\`js
> import { createDecodeModule } from 'draco3d';
> import { fs } from 'node:fs'
> 
> const wasmBuffer = fs.readFileSync('/path/to/add.wasm');
> 
> createDecodeModule( wasm: wasmBuffer );
> \`\`\`
> 
> And this code in the browser:
> 
> \`\`\`js
> import { createDecodeModule } from 'draco3d';
> 
> const wasmBuffer = await fetch( '/path/to/add.wasm');
> 
> createDecodeModule( wasm: wasmBuffer );
> \`\`\`
> 
> And both scenarios would share the same typing and the same ES module.
> 
> I know the is a big ask so it probably won't happen, but I figured I'd share a way forward that seems reasonable. Thanks for your attention.

Not their fault that packaging WASM is quite difficult today, but I think they’re [leaning on the CDN distribution method a bit too much](https://github.com/google/draco/issues/1046).

---

<div class="post-metadata">

**Author:** ![Anish\_Kumar](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/anish_kumar/32/39755_2.png) [@Anish\_Kumar](https://discourse.threejs.org/u/Anish_Kumar)\
**Post date:** [February 25, 2024, 10:59am UTC](https://discourse.threejs.org/t/bundling-threejs-project-with-dracoloader-webworker/17205/12 "2024-02-25T10:59:43Z")

</div>

Hey Hii @drcmda

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](https://github.com/Anish-Someashwara/Webpack-Draco-Test) 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.

Try it, and let me know where I am lacking.

Thanks!

---

<div class="post-metadata">

**Author:** ![drcmda](https://avatars.discourse-cdn.com/v4/letter/d/91b2a8/32.png) [@drcmda](https://discourse.threejs.org/u/drcmda)\
**Post date:** [February 25, 2024, 12:50pm UTC](https://discourse.threejs.org/t/bundling-threejs-project-with-dracoloader-webworker/17205/13 "2024-02-25T12:50:31Z")

</div>

```jsx
this.loadGltfByUrl('../static/Fox-draco.gltf')

```

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”](https://github.com/Anish-Someashwara/Webpack-Draco-Test/blob/63293b6ac9cd7e81ac4f1f2917e5be90cbe1e8c5/static/Fox-draco.gltf#L102-L106), 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.

1. 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
2. if you use a \*.glb instead of a \*.gltf, then it contains everything in one, with or without draco. less room for errors.

---

<div class="post-metadata">

**Author:** ![Anish\_Kumar](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/anish_kumar/32/39755_2.png) [@Anish\_Kumar](https://discourse.threejs.org/u/Anish_Kumar)\
**Post date:** [February 26, 2024, 6:48pm UTC](https://discourse.threejs.org/t/bundling-threejs-project-with-dracoloader-webworker/17205/14 "2024-02-26T18:48:02Z")

</div>

@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](https://github.com/Anish-Someashwara/Webpack-Draco-Test)) I have provided and try to experiment the things.

Thanks!

---

<div class="post-metadata">

**Author:** ![Hudson\_Spangler](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/hudson_spangler/32/47900_2.png) [@Hudson\_Spangler](https://discourse.threejs.org/u/Hudson_Spangler)\
**Post date:** [May 19, 2024, 8:22am UTC](https://discourse.threejs.org/t/bundling-threejs-project-with-dracoloader-webworker/17205/15 "2024-05-19T08:22:11Z")

</div>

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.
