Search code examples
clojureclojurescriptleiningenfigwheel

Lein Figwheel Compile Error


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"]]

Solution

  • 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.