nounderline
nounderline3w ago

How to exclude code and imports from deno compile binary?

I'd like to exclude some parts of code (mostly related to client bundling) from deno compile library. Is it even possible?
8 Replies
kenos
kenos3w ago
you would need to look at your bundler's documentation for stripping code not marked for clients
Leokuma
Leokuma3w ago
If I'm understanding your question correctly, you can only exclude code that is not used during the client execution of your program
nounderline
nounderlineOP3w ago
Sorry for lack of clarity. I use deno compile and I'd like to exclude some development libraries that I don't need in production. I don't use any bundler deno compile doesn't execute the program and it statically analyze imports to amke sure it includes all files. I'm looking for a way to exclude pieces of code during that step.
Leokuma
Leokuma3w ago
I dont think there's a "native" Deno way to do that You could try to use dynamic imports instead of static imports so that Deno only fetches them when they are called. If they are never called in production, they will never be fetched I'm not sure what the behavior is with JSR, but another possible strategy would be to have 2 jsr.json or 2 deno.json, one for dev and another for production. You can also consider having 2 entrypoints to your app, like main.ts and dev.ts. I'm not sure if any of those would work for you, though
kenos
kenos3w ago
no idea if this stuff is treeshaked
nounderline
nounderlineOP3w ago
Problem with dynamic import approach is that they will get included in the final binary built by deno compile. atm my binary weights almost 200mb because it includes all imports (including dynamic ones.) It's too bad deno compile doesn't do proper bundling. The whole idea is to provide optimized and lean binary. Without treeshaking things go really big (like my 200mb binary.)
raunioroo
raunioroo3w ago
I would think having 2 entrypoints like leokuma said, would be the "right" way. Deno only bundles the files that are actually used/imported beginning from the entrypoint module. One could say it's treeshaking at the file level, not invidual export level, and if the code/dependencies is properly organized, that's all the "treeshaking" you need. If your modules import a bunch of unneeded stuff, you might want to look into how you do import dependencies in general, you might be doing something wrong (or at least suboptimally). Common mistake is to use deps.ts approach to specify dependencies. That indeed tends to cause a bunch of unneeded code being loaded/included in the graph. Better to use import maps, which won't actually load the modules unless they are actually, directly used/imported by the entrypoint or it's dependencies. In any case, Deno compile binaries will always be very large, since they contain an almost complete version of deno + your code.
Leokuma
Leokuma3w ago
Sorry, I wasn't aware that this behavior changed. I think it wasn't like that before But if you assign the filename to a variable, it doesn't get included:
const imp = './my-debug.ts';
await import(imp);
const imp = './my-debug.ts';
await import(imp);
Or this:
await import(import.meta.resolve('./my-debug.ts'));
await import(import.meta.resolve('./my-debug.ts'));