duct-framework / module.cljs

Duct module for developing and compiling ClojureScript
2 stars 6 forks source link

Compilation fails on (reset) #3

Closed snichme closed 7 years ago

snichme commented 7 years ago

Not sure if this is an issue or just something with my setup (in latter case I need help)

I have a project where I'm using om.next and when I start up duct everything works fine but after any change in a .cljs file and a (reset) the compilation fails, see log below

I should also mention that doing a (clear) doesn't help, but it works again after restarting the repl.

I don't know where to begin looking so if anyone know why this happens or could point me where I should start to look.

$ lein repl
nREPL server started on port 63133 on host 127.0.0.1 - nrepl://127.0.0.1:63133
REPL-y 0.3.7, nREPL 0.2.12
Clojure 1.9.0-alpha16
Java HotSpot(TM) 64-Bit Server VM 1.8.0_60-b27
    Docs: (doc function-name-here)
          (find-doc "part-of-name-here")
  Source: (source function-name-here)
 Javadoc: (javadoc java-object-or-class-here)
    Exit: Control+D or (exit) or (quit)
 Results: Stored in vars *1, *2, *3, an exception in *e

user=> (dev)
:loaded
dev=> (go)
[rabbitmq] connecting to  {:host localhost, :port 5672, :username guest, :password guest, :vhost /}
[rabbitmq] connected. Channel id: 1
:duct.server.http.jetty/starting-server {:port 3000}
Compiling "/Users/mange/workspace/checker/dapp/target/resources/dapp/public/js/main.js" from ["dev/src" "src"]...
Successfully compiled "/Users/mange/workspace/checker/dapp/target/resources/dapp/public/js/main.js" in 4.126 seconds.
notifying browser that file changed:  target/resources/dapp/public/js/goog/deps.js
notifying browser that file changed:  target/resources/dapp/public/js/cljs_deps.js
notifying browser that file changed:  out/dapp/util.js
notifying browser that file changed:  out/dapp/client.js
notifying browser that file changed:  out/dapp/core.js
notifying browser that file changed:  out/dapp/parser.js
notifying browser that file changed:  out/dapp/ui.js
notifying browser that file changed:  out/dapp/router.js
:initiated
dev=> (reset)
Closed connection to rabbitmq
:reloading (om.util om.tempid om.transit duct.router.cascading duct.middleware.web cljs.tagged-literals cljs.env cljs.analyzer om.next.protocols cljs.analyzer.api om.next.impl.parser om.next duct.middleware.web-test duct.handler.static duct.module.web dapp.endpoint.example dapp.endpoint.example-test dapp.component.parser dapp.main cljs.stacktrace dapp.endpoint.api compassus.util dev compassus.core dapp.endpoint.app bidi.bidi dapp.component.rabbitmq duct.module.web-test user)
[rabbitmq] connecting to  {:host localhost, :port 5672, :username guest, :password guest, :vhost /}
[rabbitmq] connected. Channel id: 1
Compiling "/Users/mange/workspace/checker/dapp/target/resources/dapp/public/js/main.js" from ["dev/src" "src"]...
Failed to compile "/Users/mange/workspace/checker/dapp/target/resources/dapp/public/js/main.js" in 0.36 seconds.
----  Could not Analyze  src/cljs/dapp/ui.cljs   line:12  column:1  ----

   at line 12 src/cljs/dapp/ui.cljs

  10  ;     (.format c value)))
  11
  12  (defui Project
      ^---  at line 12 src/cljs/dapp/ui.cljs
  13    static om/Ident
  14    (ident [this props]
  15           [:project/by-id (:project/id props)])

----  Analysis Error : Please see src/cljs/dapp/ui.cljs  ----
:resumed
dev=>

No matter what I change it always complains about the same thing.

project.clj

(defproject dapp "0.1.0-SNAPSHOT"
  :description "FIXME: write description"
  :url "http://example.com/FIXME"
  :min-lein-version "2.0.0"
  :dependencies [[org.clojure/clojure "1.9.0-alpha16"]
                 [org.clojure/core.async "0.3.443"]
                 ;[com.cognitect/transit-clj "0.8.300"]
                 [com.cognitect/transit-cljs "0.8.239"]
                 [com.novemberain/langohr "4.0.0"]

                 [duct/core "0.4.0"]
                 [duct/module.logging "0.2.0"]
                 [duct/module.web "0.5.0"]
                 [duct/module.cljs "0.2.2"]

                 [org.omcljs/om "1.0.0-beta1"]
                 [compassus "1.0.0-alpha3"]
                 [bidi "2.1.1"]
                 [kibu/pushy "0.3.7"]
                 [cheshire "5.7.1"]]
  :plugins [[duct/lein-duct "0.9.0-alpha5"]
            [lein-ancient "0.6.10"]]
  :main ^:skip-aot dapp.main
  :duct {:config-paths ["resources/dapp/config.edn"]}
  :source-paths ["src/clj" "src/cljc"]
  :resource-paths ["resources" "target/resources"]
  :prep-tasks     ["javac" "compile" ["duct" "compile"]]
  :profiles
  {:dev     [:project/dev :profiles/dev]
   :repl    {:prep-tasks   ^:replace ["javac" "compile"]
             :repl-options {:init-ns user
                            :nrepl-middleware [cemerick.piggieback/wrap-cljs-repl]}}
   :uberjar {:aot :all}
   :profiles/dev {}
   :project/dev  {:source-paths   ["dev/src/clj" "dev/src/cljc"]
                  :resource-paths ["dev/resources"]
                  :dependencies   [[integrant/repl "0.2.0"]
                                   [eftest "0.3.1"]
                                   [kerodon "0.8.0"]]}})

ui.cljs

(ns dapp.ui
  (:require [om.next :as om :refer-macros [defui]]
            [om.dom :as dom]
            [dapp.router :as router]
            [clojure.string :as str]))

; (defn currency [value]
;  (let [c (NumberFormat. (.. NumberFormat -Format -CURRENCY))]
;     (.format c value)))

(defui Project
  static om/Ident
  (ident [this props]
         [:project/by-id (:project/id props)])
  static om/IQuery
  (query [this]
         [:project/id :project/title :project/running :project/url :project/checkers])
  Object
  (render [this]
          (dom/div nil (str  "Project: " (om/props this)))))

(def project-view (om/factory Project {:keyfn :project/id}))
weavejester commented 7 years ago

I can reproduce the error, but unfortunately I don't know what's causing it, or how to work around it.

It's either a bug in Figwheel, or a bug in ClojureScript. ClojureScript is the latest version, but the Figwheel dependency lags behind a little.

I'll probably be updating Figwheel sometime soon, but because Figwheel has no stable low-level API, it usually takes a few days of effort to upgrade, even between minor versions. It's a huge timesink.

I don't know whether upgrading Figwheel will help or not, but when I get around to doing that, you can try updating and see if that will help. Until then, I'm afraid I can't think of anything to help.

snichme commented 7 years ago

If I do a lein clean and remove target directory and rerun the same as above I first get this error:

  java.lang.IllegalStateException: Alias env already exists in namespace cljs.core, aliasing cljs.env, compiling:(cljs/core.cljc:1:1)

And after that it seems like all requires are messed up. In my core.cljs I get

WARNING: Use of undeclared Var dapp.core/read at line 26
WARNING: Use of undeclared Var dapp.core/mutate at line 27
WARNING: Use of undeclared Var dapp.core/parser at line 34
WARNING: Use of undeclared Var dapp.core/transit-post at line 35
WARNING: Use of undeclared Var dapp.core/reconciler at line 44
WARNING: Use of undeclared Var dapp.core/atom at line 49
WARNING: Use of undeclared Var cljs.core/not at line 51
WARNING: Use of undeclared Var cljs.core/deref at line 51
WARNING: Use of undeclared Var dapp.core/mounted? at line 51
WARNING: Use of undeclared Var dapp.core/app at line 53
WARNING: Use of undeclared Var dapp.core/app at line 54
WARNING: Use of undeclared Var dapp.core/swap! at line 55
WARNING: Use of undeclared Var dapp.core/mounted? at line 55
WARNING: Use of undeclared Var dapp.core/not at line 55
WARNING: Use of undeclared Var dapp.core/app at line 57
WARNING: Use of undeclared Var dapp.core/app at line 59
WARNING: Use of undeclared Var dapp.core/get at line 60
WARNING: Use of undeclared Var dapp.core/app at line 60

and in ui.cljs the same as above, something with the required macro defui.

Maybe this could help

sniperliu commented 7 years ago

Hope below helps, below is the stacktrace I got when (reset).

java.lang.NullPointerException: null
 at clojure.core$deref_future.invokeStatic (core.clj:2297)
    clojure.core$deref.invokeStatic (core.clj:2317)
    clojure.core$deref.invoke (core.clj:2303)
    cljs.analyzer$parse_ns$fn__4635.invoke (analyzer.cljc:3381)
    cljs.analyzer$parse_ns.invokeStatic (analyzer.cljc:3353)
    cljs.analyzer$parse_ns.invoke (analyzer.cljc:3332)
    cljs.analyzer$parse_ns.invokeStatic (analyzer.cljc:3343)
    cljs.analyzer$parse_ns.invoke (analyzer.cljc:3332)
    cljs.compiler$find_source.invokeStatic (compiler.cljc:1508)
    cljs.compiler$find_source.invoke (compiler.cljc:1507)
    clojure.core$map$fn__5406.invoke (core.clj:2735)
    clojure.lang.LazySeq.sval (LazySeq.java:40)
    clojure.lang.LazySeq.seq (LazySeq.java:56)
    clojure.lang.RT.seq (RT.java:525)
    clojure.core$seq__4944.invokeStatic (core.clj:137)
    clojure.core$reduce1.invokeStatic (core.clj:922)
    clojure.core$set.invokeStatic (core.clj:4065)
    clojure.core$set.invoke (core.clj:4057)
    cljs.closure$add_dependency_sources.invokeStatic (closure.clj:833)
    cljs.closure$add_dependency_sources.invoke (closure.clj:825)
    cljs.closure$build.invokeStatic (closure.clj:2288)
    cljs.closure$build.invoke (closure.clj:2222)
    cljs.build.api$build.invokeStatic (api.clj:202)
    cljs.build.api$build.invoke (api.clj:189)
    figwheel_sidecar.components.cljs_autobuild$cljs_build.invokeStatic (cljs_autobuild.clj:28)
    figwheel_sidecar.components.cljs_autobuild$cljs_build.invoke (cljs_autobuild.clj:27)
    figwheel_sidecar.build_middleware.injection$hook$fn__52523.invoke (injection.clj:197)
    figwheel_sidecar.components.cljs_autobuild$notify_command_hook$fn__52903.invoke (cljs_autobuild.clj:68)
  figwheel_sidecar.components.cljs_autobuild$figwheel_start_and_end_messages$fn__52895.invoke (cljs_autobuild.clj:48)
    figwheel_sidecar.build_middleware.notifications$hook$fn__52764.invoke (notifications.clj:179)
    figwheel_sidecar.build_middleware.clj_reloading$hook$fn__52821.invoke (clj_reloading.clj:94)
    figwheel_sidecar.build_middleware.javascript_reloading$hook$fn__52854.invoke (javascript_reloading.clj:48)
    figwheel_sidecar.components.cljs_autobuild$color_output$fn__52907.invoke (cljs_autobuild.clj:79)
    duct.server.figwheel$start_build.invokeStatic (figwheel.clj:79)
    duct.server.figwheel$start_build.invoke (figwheel.clj:78)
    duct.server.figwheel$build_cljs.invokeStatic (figwheel.clj:99)
    duct.server.figwheel$build_cljs.invoke (figwheel.clj:93)
    duct.server.figwheel$eval53374$fn__53376.invoke (figwheel.clj:107)
    clojure.lang.MultiFn.invoke (MultiFn.java:233)
    integrant.core$try_build_action.invokeStatic (core.cljc:199)
    integrant.core$try_build_action.invoke (core.cljc:198)
    integrant.core$build_key.invokeStatic (core.cljc:206)
    integrant.core$build_key.invoke (core.cljc:203)
    clojure.core$partial$fn__5380.invoke (core.clj:2605)
    clojure.core.protocols$fn__7665.invokeStatic (protocols.clj:167)
    clojure.core.protocols/fn (protocols.clj:124)
    clojure.core.protocols$fn__7620$G__7615__7629.invoke (protocols.clj:19)
    clojure.core.protocols$seq_reduce.invokeStatic (protocols.clj:31)
    clojure.core.protocols$fn__7648.invokeStatic (protocols.clj:75)
    clojure.core.protocols/fn (protocols.clj:75)
    clojure.core.protocols$fn__7594$G__7589__7607.invoke (protocols.clj:13)
    clojure.core$reduce.invokeStatic (core.clj:6704)
    clojure.core$reduce.invoke (core.clj:6686)
    integrant.core$build.invokeStatic (core.cljc:221)
    integrant.core$build.invoke (core.cljc:209)
    integrant.core$init.invokeStatic (core.cljc:276)
    integrant.core$init.invoke (core.cljc:268)
    integrant.core$init.invokeStatic (core.cljc:273)
    integrant.core$init.invoke (core.cljc:268)
    integrant.repl$resume$fn__54518.invoke (repl.clj:46)
    clojure.lang.AFn.applyToHelper (AFn.java:154)
    clojure.lang.AFn.applyTo (AFn.java:144)
    clojure.lang.Var.alterRoot (Var.java:305)
    clojure.core$alter_var_root.invokeStatic (core.clj:5414)
    clojure.core$alter_var_root.doInvoke (core.clj:5409)
    clojure.lang.RestFn.invoke (RestFn.java:425)
    integrant.repl$resume.invokeStatic (repl.clj:46)
    integrant.repl$resume.invoke (repl.clj:42)
    clojure.lang.Var.invoke (Var.java:377)
    clojure.tools.namespace.repl$do_refresh.invokeStatic (repl.clj:100)
    clojure.tools.namespace.repl$do_refresh.invoke (repl.clj:82)
    clojure.tools.namespace.repl$refresh.invokeStatic (repl.clj:145)
    clojure.tools.namespace.repl$refresh.doInvoke (repl.clj:128)
    clojure.lang.RestFn.invoke (RestFn.java:421)
    integrant.repl$reset.invokeStatic (repl.clj:52)
    integrant.repl$reset.invoke (repl.clj:50)
    dev$eval73007.invokeStatic (form-init492288447919556848.clj:131)
    dev$eval73007.invoke (form-init492288447919556848.clj:131)
    clojure.lang.Compiler.eval (Compiler.java:7005)
    clojure.lang.Compiler.eval (Compiler.java:6968)
    clojure.core$eval.invokeStatic (core.clj:3194)
    clojure.core$eval.invoke (core.clj:3190)
    clojure.main$repl$read_eval_print__8372$fn__8375.invoke (main.clj:242)
    clojure.main$repl$read_eval_print__8372.invoke (main.clj:242)
    clojure.main$repl$fn__8381.invoke (main.clj:260)
    clojure.main$repl.invokeStatic (main.clj:260)
    clojure.main$repl.doInvoke (main.clj:176)
    clojure.lang.RestFn.applyTo (RestFn.java:137)
    clojure.core$apply.invokeStatic (core.clj:657)
    clojure.core$apply.invoke (core.clj:652)
    refactor_nrepl.ns.slam.hound.regrow$wrap_clojure_repl$fn__28303.doInvoke (regrow.clj:18)
    clojure.lang.RestFn.invoke (RestFn.java:1523)
    clojure.tools.nrepl.middleware.interruptible_eval$evaluate$fn__1127.invoke (interruptible_eval.clj:87)
    clojure.lang.AFn.applyToHelper (AFn.java:152)
    clojure.lang.AFn.applyTo (AFn.java:144)
    clojure.core$apply.invokeStatic (core.clj:657)
    clojure.core$with_bindings_STAR_.invokeStatic (core.clj:1970)
    clojure.core$with_bindings_STAR_.doInvoke (core.clj:1970)
    clojure.lang.RestFn.invoke (RestFn.java:425)
    clojure.tools.nrepl.middleware.interruptible_eval$evaluate.invokeStatic (interruptible_eval.clj:85)
    clojure.tools.nrepl.middleware.interruptible_eval$evaluate.invoke (interruptible_eval.clj:55)
    clojure.tools.nrepl.middleware.interruptible_eval$interruptible_eval$fn__1172$fn__1175.invoke (interruptible_eval.clj:222)
    clojure.tools.nrepl.middleware.interruptible_eval$run_next$fn__1167.invoke (interruptible_eval.clj:190)
    clojure.lang.AFn.run (AFn.java:22)
    java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1142)
    java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:617)
    java.lang.Thread.run (Thread.java:745)
scottlowe commented 7 years ago

I've got similar issue and decided to have a look at upgrading Figwheel.

I've not managed to fix the issue yet, however: if Duct Figwheel should be updated to the latest Figwheel version in the near future, then it's worth noting that Figwheel will ignore files with names which begin with cljs when reloading.

I thought that I should mention it here, given that this Figwheel peculiarity could result in a potentially confusing time-sink for one of us.

https://github.com/bhauman/lein-figwheel/issues/560

scottlowe commented 7 years ago

I would like to tentatively state that I believe I've fixed this issue with reset in my particular codebase, which also has shared cljc Reagent templates as well as clj and cljs files.

The issue was fixed by telling clojure.tools.namespace which directories to scan during refresh, and hence work out the correct dependency order before reloading namespaces.

I believe this is seen in Duct template apps because of the dev directory which is at the same level as src, but I could be wrong. Certainly the original reporter of this issue @snichme has the following additional source paths in his project file:

:project/dev  {:source-paths   ["dev/src/clj" "dev/src/cljc"]

... and I have a similar config.

Nonetheless, the fix is to put something like the following in a namespace which is loaded by the REPL:

(clojure.tools.namespace.repl/set-refresh-dirs "dev" "src" "test")

In a Duct project this would typically be at the bottom of the my-project-name.dev namespace in the dev.clj file .

So this doesn't seem to be an issue with module.cljs itself, but it might be worth tweaking the Duct template if this turns out to fix other peoples issues.

Downside is that the unsuspecting user of the template would have to know about this extra config location and keep both code locations updated/synced with these source path values. 🤔

snichme commented 7 years ago

And I can confirm that adding that line for setting refresh dirs solve it for me as well.

weavejester commented 7 years ago

Ah, excellent. Thanks for the diagnosis @scottlowe, and the confirmation @snichme. I'll add the extra line to the template.