1

I've been with figwheel for most of the day, then suddenly after a restart (not the first) it started to fail to compile.

I get the following message when I run lein figwheel.

Figwheel: Starting server at http://localhost:3449
Figwheel: Watching build - dev
[0mCompiling "resources/public/js/compiled/game.js" from ["src"]...
{:file #object[java.net.URL 0x79b3937a "file:/home/dan/dev/org/danjoe/game/src/game/state.cljs"], :line 1, :column 1, :tag :cljs/analysis-error}
ANALYSIS ERROR:  at line 1 file:/home/dan/dev/org/danjoe/game/src/game/state.cljs on file file:/home/dan/dev/org/danjoe/game/src/game/state.cljs, line 1, column 1
Subprocess failed

I checked out some stable code from earlier and it still fails.

I blew away everything in my ~/.m2 directory and went again. I checked out a new copy of the repo and got the same error there.

The only meaningful part of the error is the reference to an ANALYSIS ERROR on line 1 of some file — just for the sake of my sanity, here it is.

(ns game.state
  (:refer-clojure :exclude [get])
  (:require [reagent.core :as reagent]
            [game.views.heroes :as default-view]))

If I go to that file and deliberately break the namespace (switch it to something incorrect) then run lein figwheel again, the analysis error simply switches to point at another file in my project instead. If I break all the namespaces, it then starts to throw analysis errors for line 2 (or wherever the next s-expression is).

Here are the project dependencies.

:dependencies [[org.clojure/clojure "1.7.0"]
              [org.clojure/clojurescript "1.7.170"]
              [org.clojure/core.async "0.2.374"]
              [reagent "0.5.0"]
              [secretary "1.2.0"]]

And the plugins I'm using.

  :plugins [[lein-cljsbuild "1.1.1"]
           [lein-figwheel "0.5.0-1"]]
Dan Prince
  • 29,491
  • 13
  • 89
  • 120
  • removing `.m2` should never help - artifacts are immutable once published. Clojurescript often erroneously caches partial results. Use `lein clean` to get a fresh compile without any cache. – noisesmith Jan 03 '16 at 22:12
  • Yeah, `lein clean ` came first of all. Forgot to mention. I switched over to a clojars mirror today and wondered if a dodgy network connection could have messed up a download into `.m2`. – Dan Prince Jan 03 '16 at 22:25

2 Answers2

2

It sounds like you may have some cached javascript which is causing the compile to fail.There are lots of things which can cause this, but I have run into this problem when I've updated a dependency to use a later version. The problem is that figwheel does not realise your cljs file depends on the changed dependency version, so does not re-compile the source.

The fix is to run lein clean. However, note that you also need to set the :clean-targets key in your project.clj file. Thie value is a list of directories to be cleaned when you run lein clean. By default, it just cleans what is below target. However, most people tend to put their javascript below resources/public. I have the following in my project.clj

:clean-targets ^{:protect false} [:target-path
                                    [:cljsbuild :builds :app :compiler
                                     :output-dir]
                                    [:cljsbuild :builds :app :compiler
                                     :output-to]]

which basically adds the directories where I store output from cljsbuild to the set of directories defined in :target-path. Running lein clean will now remove what is in :output-dir and :output-to. Note that you must include the :protect false value otherwise lein will ignore your additions.

Tim X
  • 4,158
  • 1
  • 20
  • 26
  • Even after running `lein clean` with updated targets, and manually checking that all the built JS is gone, I still get the analysis error when I try to compile. – Dan Prince Jan 05 '16 at 05:43
  • It even happens if I create a completely new project then pull the existing src folder into it. That way there's a guarantee that there's no cached code messing things up. – Dan Prince Jan 06 '16 at 08:40
  • My suggestion would be to post both your complete project.clj file and the state.cljs file. One of the things I notice is that our excluding the standard clojure 'get' command - why? Another alternativve is to make your project available on github and maybe I can clone it and see why your getting the error. – Tim X Jan 06 '16 at 23:57
  • My namespace was exposing a different get method, didn't want it to be implicitly shadowed. With the help of a few others, identified the problem and got an analyzer bug fixed. Thanks for the help though. – Dan Prince Jan 07 '16 at 03:13
0

The error ended up being a circular dependency, but due to a bug in Clojurescript 1.7.170 the analyzer wasn't catching the dependency and instead recursively analyzing both dependencies in an infinite cycle (until the stack overflowed).

The bug is now fixed in master, but I'll leave a rundown of how it was identified here anyway.

  1. Use the standalone Clojurescript compiler to make sure that the tooling isn't swallowing errors.
  2. Compile with the {:verbose true} option.

See the debugging output start to show the circular dependency:

Reading analysis cache for jar:file:/home/dan/Downloads/cljs.jar!/cljs/core.cljs
Compiling src/game/ui/widgets.cljs
Analyzing file:/tmp/lispjam/src/game/state.cljs
Analyzing file:/tmp/lispjam/src/game/views/heroes.cljs
Analyzing file:/tmp/lispjam/src/game/state.cljs
Analyzing file:/tmp/lispjam/src/game/views/heroes.cljs
Analyzing file:/tmp/lispjam/src/game/state.cljs
Analyzing file:/tmp/lispjam/src/game/views/heroes.cljs
Analyzing file:/tmp/lispjam/src/game/state.cljs
Analyzing file:/tmp/lispjam/src/game/views/heroes.cljs
Analyzing file:/tmp/lispjam/src/game/state.cljs
Analyzing file:/tmp/lispjam/src/game/views/heroes.cljs
Analyzing file:/tmp/lispjam/src/game/state.cljs
...

Resolving the circular dependency fixed everything, but in future versions of Clojurescript, you should get a compile time analysis warning, letting you know that your code has a circular dependency.

Dan Prince
  • 29,491
  • 13
  • 89
  • 120