reagent-project / reagent-template

A Leiningen template for projects using Reagent.
MIT License
394 stars 55 forks source link

Warning when running Figwheel without cleaning #132

Open raxod502 opened 7 years ago

raxod502 commented 7 years ago

In short, if I run lein figwheel twice, without cleaning in between, then in the second session I get a compiler warning any time I try to access a variable—even though the variable is defined, and its value is correctly printed.

Here are the precise steps to reproduce, along with my version and OS information:

Temporary % neofetch
                -/+:.           raxod502@Radon-MBP-New.local
               :++++.           ----------------------------
              /+++/.            OS: OS X El Capitan 10.11.6 15G1212 x86_64
      .:-::- .+/:-``.::-        Model: MacBookPro11,3
   .:/++++++/::::/++++++/:`     Kernel: 15.6.0
 .:///////////////////////:`    Uptime: 23 hours, 36 minutes
 ////////////////////////`      Packages: 365
-+++++++++++++++++++++++`       Shell: zsh 5.2
/++++++++++++++++++++++/        DE: Aqua
/sssssssssssssssssssssss.       WM: Quartz Compositor
:ssssssssssssssssssssssss-      Terminal: iTerm2
 osssssssssssssssssssssssso/`   CPU: Intel i7-4980HQ (8) @ 2.80GHz
 `syyyyyyyyyyyyyyyyyyyyyyyy+`   GPU: Intel Iris Pro, NVIDIA GeForce GT 750M
  `ossssssssssssssssssssss/     Memory: 3187MB / 16384MB
    :ooooooooooooooooooo+.      ​
     `:+oo+/:-..-:/+o+/-        ████████████████████████
                                ​

Temporary % rm ~/.lein/profiles.clj
Temporary % lein --version
Leiningen 2.7.1 on Java 1.8.0_112 Java HotSpot(TM) 64-Bit Server VM
Temporary % lein new reagent funk
Generating fresh 'lein new' Reagent project.
Temporary % cd funk
funk % lein figwheel
Figwheel: Cutting some fruit, just a sec ...
Figwheel: Validating the configuration found in project.clj
Figwheel: Configuration Valid :)
Figwheel: Starting server at http://0.0.0.0:3449
Figwheel: Watching build - app
Figwheel: Cleaning build - app
Compiling "target/cljsbuild/public/js/app.js" from ["src/cljs" "src/cljc" "env/dev/cljs"]...
Successfully compiled "target/cljsbuild/public/js/app.js" in 9.21 seconds.
Figwheel: Starting CSS Watcher for paths  ["resources/public/css"]
Figwheel: Starting nREPL server on port: 7002
Launching ClojureScript REPL for build: app
Figwheel Controls:
          (stop-autobuild)                ;; stops Figwheel autobuilder
          (start-autobuild [id ...])      ;; starts autobuilder focused on optional ids
          (switch-to-build id ...)        ;; switches autobuilder to different build
          (reset-autobuild)               ;; stops, cleans, and starts autobuilder
          (reload-config)                 ;; reloads build config and resets autobuild
          (build-once [id ...])           ;; builds source one time
          (clean-builds [id ..])          ;; deletes compiled cljs target files
          (print-config [id ...])         ;; prints out build configurations
          (fig-status)                    ;; displays current state of system
  Switch REPL build focus:
          :cljs/quit                      ;; allows you to switch REPL to another build
    Docs: (doc function-name-here)
    Exit: Control+C or :cljs/quit
 Results: Stored in vars *1, *2, *3, *e holds last exception object
Prompt will show when Figwheel connects to your application
To quit, type: :cljs/quit
cljs.user=> funk.core/home-page
#object[funk$core$home_page "function funk$core$home_page(){
return new cljs.core.PersistentVector(null, 3, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"div","div",1057191632),new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"h2","h2",-372662728),"Welcome to funk"], null),new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"div","div",1057191632),new cljs.core.PersistentVector(null, 3, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"a","a",-2123407586),new cljs.core.PersistentArrayMap(null, 1, [new cljs.core.Keyword(null,"href","href",-793805698),"/about"], null),"go to about page"], null)], null)], null);
}"]
cljs.user=> ^D
funk % lein figwheel
Figwheel: Cutting some fruit, just a sec ...
Figwheel: Validating the configuration found in project.clj
Figwheel: Configuration Valid :)
Figwheel: Starting server at http://0.0.0.0:3449
Figwheel: Watching build - app
Compiling "target/cljsbuild/public/js/app.js" from ["src/cljs" "src/cljc" "env/dev/cljs"]...
Successfully compiled "target/cljsbuild/public/js/app.js" in 1.323 seconds.
Figwheel: Starting CSS Watcher for paths  ["resources/public/css"]
Figwheel: Starting nREPL server on port: 7002
Launching ClojureScript REPL for build: app
Figwheel Controls:
          (stop-autobuild)                ;; stops Figwheel autobuilder
          (start-autobuild [id ...])      ;; starts autobuilder focused on optional ids
          (switch-to-build id ...)        ;; switches autobuilder to different build
          (reset-autobuild)               ;; stops, cleans, and starts autobuilder
          (reload-config)                 ;; reloads build config and resets autobuild
          (build-once [id ...])           ;; builds source one time
          (clean-builds [id ..])          ;; deletes compiled cljs target files
          (print-config [id ...])         ;; prints out build configurations
          (fig-status)                    ;; displays current state of system
  Switch REPL build focus:
          :cljs/quit                      ;; allows you to switch REPL to another build
    Docs: (doc function-name-here)
    Exit: Control+C or :cljs/quit
 Results: Stored in vars *1, *2, *3, *e holds last exception object
Prompt will show when Figwheel connects to your application
To quit, type: :cljs/quit
cljs.user=> funk.core/home-page
----  Compiler Warning on   <cljs form>   line:1  column:1  ----

  Use of undeclared Var funk.core/home-page

  1  funk.core/home-page
     ^---

----  Compiler Warning  ----
#object[funk$core$home_page "function funk$core$home_page(){
return new cljs.core.PersistentVector(null, 3, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"div","div",1057191632),new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"h2","h2",-372662728),"Welcome to funk"], null),new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"div","div",1057191632),new cljs.core.PersistentVector(null, 3, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"a","a",-2123407586),new cljs.core.PersistentArrayMap(null, 1, [new cljs.core.Keyword(null,"href","href",-793805698),"/about"], null),"go to about page"], null)], null)], null);
}"]
cljs.user=>

Additional info:

yogthos commented 7 years ago

One way to fix this would be to make an alias in lein to clean before running Figwheel:

:aliases
  {"figwheel"
          ["do"
            ["clean"]
            ["npm" "install"]
            ["figwheel"]]}
raxod502 commented 7 years ago

Right, but it would seem that running lein clean all the time is undesirable, since it means all the files have to be rebuilt (might take a really long time for big projects).

yogthos commented 7 years ago

I actually ended up doing that in my projects due to similar issues. I find that I don't tend to restart Fighweel all that often, and even for a large project the initial build only takes a few seconds.

However, I do agree that ideally you shouldn't have to clean between restarts. Unfortunately, it's not really something that can be fixed in the template itself.

raxod502 commented 7 years ago

Is it a bug in Figwheel then? I can open an issue there, if that's the case.

yogthos commented 7 years ago

It does look like there's something that trips up Figwheel in your case. As a note, I just tried this locally and I'm not seeing the problem in my setup:

->lein figwheel
Figwheel: Cutting some fruit, just a sec ...
Retrieving org/clojure/clojurescript/1.9.229/clojurescript-1.9.229.pom from central
Retrieving org/clojure/clojurescript/1.7.48/clojurescript-1.7.48.pom from central
Retrieving org/clojure/clojurescript/1.9.229/clojurescript-1.9.229.jar from central
Figwheel: Validating the configuration found in project.clj
Figwheel: Configuration Valid :)
Figwheel: Starting server at http://0.0.0.0:3449
Figwheel: Watching build - app
Figwheel: Cleaning build - app
Compiling "target/cljsbuild/public/js/app.js" from ["src/cljs" "src/cljc" "env/dev/cljs"]...
Successfully compiled "target/cljsbuild/public/js/app.js" in 13.147 seconds.
Figwheel: Starting CSS Watcher for paths  ["resources/public/css"]
Figwheel: Starting nREPL server on port: 7002
Launching ClojureScript REPL for build: app
Figwheel Controls:
          (stop-autobuild)                ;; stops Figwheel autobuilder
          (start-autobuild [id ...])      ;; starts autobuilder focused on optional ids
          (switch-to-build id ...)        ;; switches autobuilder to different build
          (reset-autobuild)               ;; stops, cleans, and starts autobuilder
          (reload-config)                 ;; reloads build config and resets autobuild
          (build-once [id ...])           ;; builds source one time
          (clean-builds [id ..])          ;; deletes compiled cljs target files
          (print-config [id ...])         ;; prints out build configurations
          (fig-status)                    ;; displays current state of system
  Switch REPL build focus:
          :cljs/quit                      ;; allows you to switch REPL to another build
    Docs: (doc function-name-here)
    Exit: Control+C or :cljs/quit
 Results: Stored in vars *1, *2, *3, *e holds last exception object
Prompt will show when Figwheel connects to your application
^C⏎                                                                                                                                  
-> lein figwheel
Figwheel: Cutting some fruit, just a sec ...
Figwheel: Validating the configuration found in project.clj
Figwheel: Configuration Valid :)
Figwheel: Starting server at http://0.0.0.0:3449
Figwheel: Watching build - app
Compiling "target/cljsbuild/public/js/app.js" from ["src/cljs" "src/cljc" "env/dev/cljs"]...
Successfully compiled "target/cljsbuild/public/js/app.js" in 1.25 seconds.
Figwheel: Starting CSS Watcher for paths  ["resources/public/css"]
Figwheel: Starting nREPL server on port: 7002
Launching ClojureScript REPL for build: app
Figwheel Controls:
          (stop-autobuild)                ;; stops Figwheel autobuilder
          (start-autobuild [id ...])      ;; starts autobuilder focused on optional ids
          (switch-to-build id ...)        ;; switches autobuilder to different build
          (reset-autobuild)               ;; stops, cleans, and starts autobuilder
          (reload-config)                 ;; reloads build config and resets autobuild
          (build-once [id ...])           ;; builds source one time
          (clean-builds [id ..])          ;; deletes compiled cljs target files
          (print-config [id ...])         ;; prints out build configurations
          (fig-status)                    ;; displays current state of system
  Switch REPL build focus:
          :cljs/quit                      ;; allows you to switch REPL to another build
    Docs: (doc function-name-here)
    Exit: Control+C or :cljs/quit
 Results: Stored in vars *1, *2, *3, *e holds last exception object
Prompt will show when Figwheel connects to your application

Only other thing that I can think of to try would be to delete local Maven cache for Figwheel:

rm -rf ~/.m2/repository/figwheel*

If that doesn't help, then opening an issue for Figwheel would probably be the way to go.

raxod502 commented 7 years ago

I already tried wiping my entire Maven cache. I'll open an issue against Figwheel, but also—it looks like your Figwheel didn't connect to your browser. If you let it, does that change anything?

yogthos commented 7 years ago

Just tried, that seems to be working fine as well in my case:

─> lein figwheel
Figwheel: Cutting some fruit, just a sec ...
Figwheel: Validating the configuration found in project.clj
Figwheel: Configuration Valid :)
Figwheel: Starting server at http://0.0.0.0:3449
Figwheel: Watching build - app
Compiling "target/cljsbuild/public/js/app.js" from ["src/cljs" "src/cljc" "env/dev/cljs"]...
Successfully compiled "target/cljsbuild/public/js/app.js" in 1.145 seconds.
Figwheel: Starting CSS Watcher for paths  ["resources/public/css"]
Figwheel: Starting nREPL server on port: 7002
Launching ClojureScript REPL for build: app
Figwheel Controls:
          (stop-autobuild)                ;; stops Figwheel autobuilder
          (start-autobuild [id ...])      ;; starts autobuilder focused on optional ids
          (switch-to-build id ...)        ;; switches autobuilder to different build
          (reset-autobuild)               ;; stops, cleans, and starts autobuilder
          (reload-config)                 ;; reloads build config and resets autobuild
          (build-once [id ...])           ;; builds source one time
          (clean-builds [id ..])          ;; deletes compiled cljs target files
          (print-config [id ...])         ;; prints out build configurations
          (fig-status)                    ;; displays current state of system
  Switch REPL build focus:
          :cljs/quit                      ;; allows you to switch REPL to another build
    Docs: (doc function-name-here)
    Exit: Control+C or :cljs/quit
 Results: Stored in vars *1, *2, *3, *e holds last exception object
Prompt will show when Figwheel connects to your application
To quit, type: :cljs/quit
cljs.user=> ^C⏎                                                                                                                      
-> lein figwheel
Figwheel: Cutting some fruit, just a sec ...
Figwheel: Validating the configuration found in project.clj
Figwheel: Configuration Valid :)
Figwheel: Starting server at http://0.0.0.0:3449
Figwheel: Watching build - app
Compiling "target/cljsbuild/public/js/app.js" from ["src/cljs" "src/cljc" "env/dev/cljs"]...
Successfully compiled "target/cljsbuild/public/js/app.js" in 1.238 seconds.
Figwheel: Starting CSS Watcher for paths  ["resources/public/css"]
Figwheel: Starting nREPL server on port: 7002
Launching ClojureScript REPL for build: app
Figwheel Controls:
          (stop-autobuild)                ;; stops Figwheel autobuilder
          (start-autobuild [id ...])      ;; starts autobuilder focused on optional ids
          (switch-to-build id ...)        ;; switches autobuilder to different build
          (reset-autobuild)               ;; stops, cleans, and starts autobuilder
          (reload-config)                 ;; reloads build config and resets autobuild
          (build-once [id ...])           ;; builds source one time
          (clean-builds [id ..])          ;; deletes compiled cljs target files
          (print-config [id ...])         ;; prints out build configurations
          (fig-status)                    ;; displays current state of system
  Switch REPL build focus:
          :cljs/quit                      ;; allows you to switch REPL to another build
    Docs: (doc function-name-here)
    Exit: Control+C or :cljs/quit
 Results: Stored in vars *1, *2, *3, *e holds last exception object
Prompt will show when Figwheel connects to your application
To quit, type: :cljs/quit
cljs.user=>
raxod502 commented 7 years ago

Oh wait, you didn't try to evaluate a variable. That's when the warning happens.

cljs.user=> funk.core/home-page
----  Compiler Warning on   <cljs form>   line:1  column:1  ----

  Use of undeclared Var funk.core/home-page

  1  funk.core/home-page
     ^---

----  Compiler Warning  ----
#object[funk$core$home_page "function funk$core$home_page(){
return new cljs.core.PersistentVector(null, 3, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"div","div",1057191632),new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"h2","h2",-372662728),"Welcome to funk"], null),new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"div","div",1057191632),new cljs.core.PersistentVector(null, 3, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"a","a",-2123407586),new cljs.core.PersistentArrayMap(null, 1, [new cljs.core.Keyword(null,"href","href",-793805698),"/about"], null),"go to about page"], null)], null)], null);
}"]
raxod502 commented 7 years ago

Cross-posted to https://github.com/bhauman/lein-figwheel/issues/511.

yogthos commented 7 years ago

Oh I see what's happening in your case. You end up in the user namespace and the funk.core namespace is not loaded. If you do (require 'funk.core), then you shouldn't get the error.

yogthos commented 7 years ago

alternatively, you could switch to the namespace by running (in-ns 'funk.core)

raxod502 commented 7 years ago

You're right. Running (require 'funk.core) first eliminates the warning. However, (in-ns 'funk.core) does not work.

I guess I'm surprised because the variable is clearly defined well enough for its value to be printed. What sort of intermediate state is the variable in where the compiler thinks it doesn't exist while it actually does? Such an intermediate state doesn't seem to exist in Clojure, only in ClojureScript.

Also, I think it's a bad idea for Figwheel to behave differently depending on whether or not lein clean is run. Regardless of the actual behavior, it should be consistent. I'm leaning towards it should always behave the same way as it currently does right after a lein clean, since the warning seems nonsensical to me.

yogthos commented 7 years ago

Yeah, I'm not sure why the namespace is loaded after running clean, and not after resuming with existing compiled sources. I agree that consistent behavior would be desirable here.