google / google/draco

Modernizing Draco package - ES modules and unifying NodeJS/Browser builds.

Open
#977 0 comments 32 reactions 0 assignees View on GitHub
enhancement Feature Request
Dominant language
C++
Stars
7.5k
Forks
1.1k
Avg merge
47m
Merged PRs (30d)
1

Description

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.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.