Open anandthakker opened 2 years ago
Here's an example demonstrating the technique: https://github.com/desmosinc/esbuild-worker-dedupe/tree/194e2b9384d70fd3a4fcff39794dd06c472cfb3f
This works as-is, but to see the problem I described above, change the import
in main.ts
into a require
(but leave the one in worker.ts
alone).
Update: okay, I guess fixing the live-binding thing isn't terrible, mostly because I found escope
to take care of analyzing variable scope, which made it straightforward to replace each import variable with __shared_modules_exports['importIdentifierName']
Updated the example repo here
But this leaves the second step basically as a manual/custom bundling step that's surely slower than esbuild would be, so I'd still be interested in whether esbuild might be able to support this somehow.
I'm hoping to bundle a large API that uses workers into a single bundle, with the worker source inlined. But straightforward approach results in too much code duplication in our case. (There's about 1MB of unminified shared code between the main entrypoint and the worker entrypoint.)
I've almost got a solution using code splitting. Roughly:
entryPoints: ['main.js', 'worker.js']
andsplitting: true
to factor out the common dependencies into a shared chunk.Run a second build that consumes those three outputs and, using some pretty outlandish transforms on the shared and worker chunks, produces a single bundle that looks like:
The problem is that, in practice, the exports from the shared module can end up looking like
export { init_shared, exported_thing }
, whereinit_shared
is a function wrapping the shared module code for lazy execution, which only works whenexported_thing
is a live binding. Since my hacky transformation changes these exports into properties on a returned object and the import of them into const variables, it breaks (exported_thing
remains undefined in the consuming scope).I guess my questions are:
[^1]: ... though maybe not that esoteric: we're doing this at Desmos for our calculator API, and we also did a very similar thing at my previous company for mapbox-gl-js.