How do I bundle with deno (with javascript) instead of esbuild?
I have the following project structure:
which produce:
I would like to create two bundles:
1. loader.mjs which contains both 'static' dependencies, those imported like:
and a dynamically imported frontend (hot-reloaded manually) like:
2. frontend.mjs which is not really a bundle but is frontend.mts de-typescripted [+minified for production]
* frontend.mjs also does
import * as THREE from "threejs"
but I want this to be marked as external when "bundling" because it will already be present in the loader.mjs bundle
* the result is that a small frontend.mjs is dynamically reloaded by loader.mjs but the common dependencies are not hot reloaded
The end result is that I have:
* loader.mjs containing the frontend-hotloader and common dependencies loaded in the html via <script>
* frontend.mjs which will be hot reloaded
I'm not sure how to do this with Deno or whether it's even the right tool. My key requirements are:
* the frontend should not reload its dependencies when hot-reloading (since the loader.mjs bundle should already contain them)
* bundling should be almost as fast as esbuild (i.e. instant, pretty much)
* it should not be a PITA
Thank you for reading this far and any advice is appreciated!
Ell3 Replies
I have a few ideas:
3. I've tried using esbuild to do this - it can do the static analysis and stuff using
"jsr:@deno/esbuild-plugin"
but then it seems to fail if I call it from the root directory.
That means I'd have to cwd
which is fine but in general it also seems like using esbuild + Deno is generally unsupported (the plugin not respecting esBuilds absWorkingDirectory
is evidence of this, IMO, as well as that there are multiple plugins with nothing seemingly officially supported)
4. I've tried using the deno_emit
+ deno_graph
API but they seem not to support importMaps or npm:
-style imports. I'm currently getting errors of this shape:
error: Uncaught (in promise) Error: Unable to output during bundling: load_transformed failed: failed to analyze module: failed to resolve npm:three@^0.179.1 from file:///home/elliot/projects/localgame/frontend/loader.mts: Cannot resolve "npm:three@^0.179.1" from "file:///home/elliot/projects/localgame/frontend/loader.mts". const ret = new Error(getStringFromWasm0(arg0, arg1));(from
createGraph
, but I'd have to re-check where exactly it comes from)
I'm just not sure what the "done thing" is.
[FYI I don't come from a web development background]
I would be happy to be wrong about deno_emit
and deno_graph
not supporting the normal imports that Deno itself supports, by the way!esbuild is the wrong tool for the job. It does no HMR and neither does
deno bundle
. They just do one thing: combine JS files into fewer files
also deno bundle
uses esbuild
internally, the difference is just that it's preconfiguredis "HMR" hot module reload? I can do that part myself manually
Well. I want to avoid reloading my frontend causing loading multiple copies of dependencies (hence shifting them to the "loader" bundle where they are statically loaded only once)
here manually means doing
import("frontend.mjs")
at runtime, something I don't expect (or want) the bundler to do for me
So I'm asking here strictly about bundling.
I don't think what I want to achieve is possible because there is no way for my frontend.mjs to consume the static esm imports from its parent loader.mjs without manually passing them down, which is annoying.
So I will just use esbuild splitting: true
instead.