a.zi is not a function on heroku but app works fine on local

Viewed 113

I have a clojurescript app deployed on Heroku that gives an error when a certain event is triggered. The event triggers fine and the effects occur on the local machine, but not online.

Here's the error that I'm getting in the console:

[Error] TypeError: a.zi is not a function. (In 'a.zi(xr.b(b))', 'a.zi' is undefined)
    (anonymous function) (app.js:1143:299)
    MG (app.js:1145:298)
    NG (app.js:1147:192)
    LG (app.js:1142:524)
    (anonymous function) (app.js:1144:242)
    MG (app.js:1145:298)
    b (app.js:1142:570)
    (anonymous function) (app.js:1065:272)

What am I to make sense of this and where to even start debugging it?

1 Answers

These two-letter function names are what you get after the Google Closure Compiler (GCC) has done its advanced optimizations.

Normally when this happens to me, it's because I'm referring into a Javascript library. Let's say library A publishes function foo ... let's assume it's published out in the browser as (effectively) window.A = { foo: function () {}; };.

Depending on how you've (:required ,,,), GCC can get confused and think that anywhere it sees foo it's allowed to rename it. It isn't. There's a few ways to tell it not to. But first, debugging:

Usually the first thing I'd do is re-deploy with :simple optimizations instead of :advanced. Your bundle size will be bigger, but nothing will have been renamed and so you can at least find the culprit in the devtools. Where you change these settings is going to vary depending on whether you're using lein-figwheel, figwheel.main, ShadowCLJS or clojurescript.main to compile your cljs:

https://clojurescript.org/reference/compiler-options#optimizations

Another trick is to turn on pseudo-names and pretty-print and re-deploy.

https://clojurescript.org/reference/compiler-options#pseudo-names https://clojurescript.org/reference/compiler-options#pretty-print

Once you find it, you might want to surround the problem code with (set! *warn-on-infer* true). This gives you some hints where you might want to provide your own compiler hints; these will also opt the (eg. (defn a-fn [^js/L.LatLng pos] (.toString pos)) would opt .toString out of GCC's renaming if you were working with leaflet).

https://clojurescript.org/guides/externs#externs-inference

Finally, this article has a bunch more tips: https://dev.solita.fi/2020/06/25/taming-cljs-advanced-compilation.html

Related