ClojureScript :advanced builds break JS interop after a compiler version bump
0 reputation · 14 Dec 2023, 05:40 UTC
Goal
I am upgrading a ClojureScript project's compiler and build tool to a newer release, and I want the existing :advanced optimization build to keep working against the third-party JavaScript libraries the app depends on. The :simple build is not a concern; the unresolved part is the aggressive renaming and dead-code elimination that :advanced applies through the Google Closure Compiler.
Constraints and uncertainty
The codebase calls into external JS libraries that are loaded at runtime rather than bundled, so property and function names must survive compilation as literal strings. Some entry points are invoked from plain JavaScript outside the ClojureScript artifact. I am unsure which of these call sites need to be guarded with goog.exportSymbol/^:export metadata versus an externs file, and whether the newer compiler/GCC pairing changed how strictly missing externs are treated. I also want to know if the js> reader macro is a safe escape hatch for the few low-level calls, or if it is equally subject to renaming of the surrounding symbols.
Questions
- After a compiler upgrade, what is the reliable way to detect which external JS names were renamed or eliminated before runtime?
- Should runtime-loaded libraries be protected with an externs file,
^:exportmetadata, or both? - Does
js>embedded code behave differently under:advancedthan under:simple?