We’re working on a more-or-less complex ClojureScript (re-frame) codebase here:
- 14k sloc
- multiple js dependencies, partially via cljsjs (e.g. three.js), but also as “raw”
:foreign-libs
Now the interesting question arises how to get advanced compilation working. This may sound like a trivial thing at first, but at least I cannot manage to solve it.
Maybe I’m actually looking at this the wrong way, because I already got my app working (no js errors at runtime) but something in the three.js logic seems to be broken (no images are being rendered, no error message).
Here are possible approaches with their respective problems:
- Generate externs with the js externs generator
- Not viable, fails with some of the dependencies
- Hand-write externs
- Not viable (in the short term), we’ve got lots of interop code and manually going through all source files and translating that to an externs file is tedious and error-prone. May become viable if all other options fail.
- Auto-generate externs via externs inference
- First problem: Even with
*warn-on-infer!*
set totrue
at the top of all source files, I strangely get no warnings even though I haven’t annotated any types and the generated js doesn’t run. That’s on the latest ClojureScript version (1.9.946) - Second problem: As a workaround, I activate source maps, generate the js and check where it fails, then go back to the source and add a type annotation there (so much for a fast feedback loop…). However, now my code runs without errors but it still isn’t displaying my three.js image even though the internal three.js state seems to be fine (checked with some
console.log
introspection of the relevant stateful three.js objects).
- First problem: Even with
- Include dependencies as js modules
- Does not seem to be viable for dependencies which itself have many dependencies. I tried bundling every dependencies with a custom
rollup.js
config as an ES6 module, but still get errors that the dependencies are missing (which may seem obvious now).
- Does not seem to be viable for dependencies which itself have many dependencies. I tried bundling every dependencies with a custom
- Include an externs file of other people who got it working
- I found this tetris project which apparently got it working some time ago and included the externs file. Same problem, no js runtime errors but also no image rendered.
In summary, I have no clue. As said above, it may be that this is not an externs problem per se but rather that advanced compilation seems to break something in three.js internally (is that even possible? or, is the minified file from cljsjs corrupted?).
I’m glad to hear any suggestions!