@tolitius hello! Can you please clarify this thing for me
In dev/user.my
namespace I have this:
(ns <http://user.my|user.my>
(:require [clojure.tools.namespace.repl :refer [refresh]]
[mount.core :as mount]))
(defn start []
(mount/in-cljc-mode)
(mount/start))
(defn stop []
(mount/stop))
(defn go []
(start)
:started)
(defn reset []
(stop)
(refresh :after '<http://user.my/go|user.my/go>)
:ok)
I want to to use a mount with cljs, more generally β sharing config on clj and cljs side
So, in src/cljc
I create namespace config.cljc
, which look like this
(ns my-lib.config
#?(:clj
(:require [config.core :refer [load-env]] ;; this is yogthos/config
[taoensso.timbre :as log]
[mount.core :refer [defstate]]))
#?(:cljs
(:require-macros [mount.core :refer [defstate]])))
#?(:clj
(defn load-config []
(log/info "loading configuration")
(load-env)))
#?(:clj
(defstate ^{:on-reload :noop} config
:start (load-config)))
#?(:cljs
(defstate ^{:on-reload :noop} frontend-environment
:start (:env @config)))
When I started repl, all states starting good, then I load namespase with config in repl and try to see whatβs happening:
;; this is clj-repl
my-lib.config> (:env @config)
{:host "localhost", :port 3001, :database "data/dev"}
;; this is cljs-repl
my-lib.config> frontend-environment
nil
my-lib.config> @frontend-environment
#object[Error Error: No protocol method IDeref.-deref defined for type undefined: ]
cljs.core.missing_protocol@http://localhost:3449/js/compiled/app.js:129:336
cljs.core._deref@http://localhost:3449/js/compiled/app.js:223:435
cljs.core.deref@http://localhost:3449/js/compiled/app.js:366:402
@http://localhost:3449/js/compiled/app.js line 3469 > eval:1:226
@http://localhost:3449/js/compiled/app.js line 3469 > eval:1:189
@http://localhost:3449/js/compiled/app.js line 3469 > eval:1:2
figwheel.client.utils.eval_helper@http://localhost:3449/js/compiled/app.js:3469:309
What I do wrong?Even in .cljs
namespaces I canβt work with mount, for example
(ns my-lib.state
(:require-macros [mount.core :refer [defstate]]))
In cljs-repl:
my-lib.state> (defstate a :start 12)
---- Compiler Warning on cljs form line:1 column:1 ----
Use of undeclared Var mount.core/running-noop?
1 (defstate a :start 12)
^---
---- Compiler Warning ----
---- Compiler Warning on cljs form line:1 column:1 ----
Use of undeclared Var mount.core/mount-it
1 (defstate a :start 12)
^---
---- Compiler Warning ----
---- Compiler Warning on cljs form line:1 column:1 ----
Use of undeclared Var mount.core/current-state
1 (defstate a :start 12)
^---
---- Compiler Warning ----
#object[ReferenceError ReferenceError: mount is not defined]
nil
@rustam.gilaztdinov you need to require mount
as well so cljs
understands how to evaluate defstate
macro (i.e. since it is using mount functions):
connected! >>
To quit, type: :cljs/quit
nil
cljs.user=> (require-macros '[mount.core :refer [defstate]])
nil
cljs.user=> (defstate a :start 12)
WARNING: Use of undeclared Var mount.core/running-noop? at line 1 <cljs repl>
WARNING: Use of undeclared Var mount.core/mount-it at line 1 <cljs repl>
WARNING: Use of undeclared Var mount.core/current-state at line 1 <cljs repl>
#'cljs.user/a
but:
cljs.user=> (require '[mount.core :as mount])
nil
cljs.user=> (defstate a :start 12)
#'cljs.user/a
cljs.user=> @a
12
doesn't work for me π
(ns my-lib.state
(:require-macros [mount.core :refer [defstate]])
(:require [mount.core :as mount]))
my-lib.state> (defstate a :start 12)
#object[ReferenceError ReferenceError: mount is not defined]
nil
ok, one problem at a time
did it fix the warnings?
i.e.
Use of undeclared Var mount.core...
yes
ok, good. which browser are you using to connect to the cljs repl?
chrome
how do you start the cljs repl?
figwheel
from cider in spacemacs
there is something off in a way cljs repl (in your case) evals the forms, in this case defstate
I use neither π so it is harder to debug, but could you start your cljs repl in a different way and try? for example I use "terminal" and "boot" to start the cljs repl.
i.e. this is what I use: https://github.com/tolitius/mount/blob/master/build.boot#L114-L119
do you know boot at all?
(i.e. use it)
it's really dumb -- but after lein clean
mount in cljs works now! π
I remember this error on cljs
side when the browser could not evaluate the forms, it was caused by the faulty repl connection. since I don't use emacs/figwheel it is harder for me to guess
ah.. ok. great π
yea, that is one of the reasons I started using boot
for everything
thx, can you help me with .cljc
files?
to avoid hours of debugging that is caused by stale state introduced by lein
maybe tools.deps
will help us in a future?
could be, have not used it yet (docs are interesting though)
agree
> can you help me with .cljc
files?
do you still have an undefined type problem?
no, another one, give me a minute, pls)
ok, I have to run, post it here. I'll look later on
I have this cljc namespace
(ns my-lib.config
(:require
#?@(:clj
[[config.core :refer [load-env]]
[taoensso.timbre :as log]
[mount.core :refer [defstate]]]
:cljs
[[mount.core :as mount]]))
#?(:cljs
(:require-macros
[mount.core :refer [defstate]])))
#?(:clj
(defn load-config []
(log/info "loading configuration")
(load-env)))
#?(:clj
(defstate ^{:on-reload :noop} config
:start (load-config)))
#?(:cljs
(defstate ^{:on-reload :noop} frontend-environment
:start (:env @config)))
and on clj-repl config works well
I want to share this config to cljs-side
In cljs-repl, when I evaluate namespace -- I see this warning
WARNING: Use of undeclared Var my-lib.config/config at line 25 /Users/..../config.cljc
and this error
my-lib.config> @frontend-environment
#object[Error Error: No protocol method IDeref.-deref defined for type undefined: ]
cljs.core/missing-protocol (jar:file:/Users/../.m2/repository/org/clojure/clojurescript/1.9.908/clojurescript-1.9.908.jar!/cljs/core.cljs:304:4)
cljs.core/-deref (jar:file:/Users/../.m2/repository/org/clojure/clojurescript/1.9.908/clojurescript-1.9.908.jar!/cljs/core.cljs:659:1)
cljs$core$deref (jar:file:/Users/../.m2/repository/org/clojure/clojurescript/1.9.908/clojurescript-1.9.908.jar!/cljs/core.cljs:1437:4)
nil
I think -- this is because defstate frontend-environment
relies to @config
, which is #?clj
related