Open danjohansson opened 3 weeks ago
It is correct that shadow-cljs treats defonce
just like def
for release builds, as generally defonce
only exists as a REPL aid so that reloading a namespace does not overwrite state you might want to keep.
There is currently no flag to turn this off. I could add one, but would rather get you away from doing something you are not supposed to be doing. def
, defonce
, defn
are all supposed to be top level forms. Embeeding a defonce
inside a defn
is nightmare fuel.
Why are you doing this in the first place?
Ok thanks for clarifying. I was surprised that it worked the way it did and not according to the Clojure documentation. I guess this would be the main argument for changing this.
We use it during initialization as a way of making sure some code only run once. Knowing that the pattern is problematic in general, I thought this would be safe. Guess I was wrong! :smile:
well, if you def
something that only runs once as a namespace is only ever loaded once in release builds.
So, (defonce x (only-ever-runs-once 1))
works just fine.
The following code gives the printout
x: 2
Expected printoutx: 1
I have tried the same code in the clojure clojurescript compiler, with the advanced mode setting turned on, without being able to reproduce.