I've been experiment with Nim + JS (not node.js) and wondering how to produce an even more compact, junk-free, final js output.
Right now, I'm compiling with:
--skipUserCfg:on --skipProjCfg:on --skipParentCfg:on --colors:off --d:danger --panics:off --mm:orc --checks:off --overflowChecks:on -d:ssl --passC:-O3 --cincludes:extras --nimcache:.cache --embedsrc:on --path:src --opt:size --listCmd --verbosity:1 --hints:on
But I'm not even sure how many of those do matter for JS.
And then compress with:
uglifyjs {BINARY} -c -m "toplevel,reserved=['A$']" -c -o {BINARY}.min.js
but still it leaves a ton of things - I bet I can spot too-long ids for example even myself.
Any ideas?
Just these options should give the same JS output as your arguments:
--d:danger --mm:orc --overflowChecks:on
--checks:off is implied by --d:danger. --overflowChecks:on overrides --d:danger and decreases performance/increases code size, unless you have a reason to have overflow checks on. --mm:orc (or just --mm:arc) mainly influnces Nim's semantic checking, so behavior of code will be changed rather than codegen, maybe it can elide some copies but I'm not sure.
--panics:off is the default, --panics:on would be the more efficient version in C but I'm not sure if it changes anything for JS.
Nim's JS output is always going to be more verbose than handwritten JS but some things like RTTI for copies etc are avoidable (ref object instead of object better reflects JS semantics, cstring instead of string can make the output more simple). There are also things like https://github.com/nim-lang/Nim/issues/8821 which should be fixed but you can maybe work around in your code sometimes. If that's still not enough then you have no choice but to investigate the code output and see what's making it so big.
Here is what I use for Stardust.dev's JS:
task clientr, "Build JS sources":
exec "nimble js -d:client -d:js -d:danger --out:out/client.js client.nim"
when defined(linux):
# Little hack, replace {val: 0, has: false, val: 0, has: false}
exec "sed -i 's/{val: 0, has: false, val: 0, has: false}/{val: 0, has: false}/g' out/client.js"
exec "closure-compiler --js out/client.js --js_output_file out/client-compiled.js"
# exec "uglifyjs out/client-compiled.js -o out/client-compiled-uglify.js -m toplevel"
cpFile("out/client-compiled.js", "out/client.js")
exec "sed -i \"s/REPLACEMEWITHTIMESTAMP/$(date +%s)/g\" out/index.html"
I used to use both closure-compiler and uglifyjs... and then uglifyjs straight up broke the JS. Closure-compiler is definitely the best though.
Hope it helps :)