【问题标题】:Lein Figwheel Compile ErrorLein Figwheel 编译错误
【发布时间】:2016-01-03 22:06:39
【问题描述】:

我大部分时间都在使用 figwheel,然后在重新启动后(不是第一次)突然开始编译失败。

我在运行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

我检查了一些之前的稳定代码,但仍然失败。

我把~/.m2 目录中的所有内容都清空了,然后又去了。我检查了一个新的 repo 副本并在那里得到了同样的错误。

错误中唯一有意义的部分是在某个文件的第 1 行对 ANALYSIS ERROR 的引用——为了我的理智,这里是。

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

如果我转到该文件并故意破坏命名空间(将其切换为不正确的名称)然后再次运行lein figwheel,则分析错误只是切换到指向我项目中的另一个文件。如果我破坏了所有的命名空间,它就会开始为第 2 行(或下一个 s 表达式所在的位置)抛出分析错误。

这是项目依赖项。

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

还有我正在使用的插件。

  :plugins [[lein-cljsbuild "1.1.1"]
           [lein-figwheel "0.5.0-1"]]

【问题讨论】:

  • 删除 .m2 永远不会有帮助 - 工件一旦发布就不可更改。 Clojurescript 经常错误地缓存部分结果。使用lein clean 获得没有任何缓存的全新编译。
  • 是的,lein clean 首先出现。忘了提。我今天切换到 clojars 镜像,想知道是否存在不可靠的网络连接会导致下载到 .m2 时出错。

标签: clojure clojurescript leiningen figwheel


【解决方案1】:

听起来您可能有一些缓存的 javascript 导致编译失败。有很多事情可能导致这种情况,但是当我更新依赖项以使用更高版本时遇到了这个问题。问题是 figwheel 没有意识到你的 cljs 文件依赖于改变的依赖版本,所以没有重新编译源。

修复方法是运行 lein clean。但是,请注意,您还需要在 project.clj 文件中设置 :clean-targets 键。这个值是运行 lein clean 时要清理的目录列表。默认情况下,它只清理低于目标的内容。但是,大多数人倾向于将他们的 javascript 放在资源/公共之下。我的 project.clj 中有以下内容

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

这基本上将我存储来自 cljsbuild 的输出的目录添加到 :target-path 中定义的目录集。运行 lein clean 现在将删除 :output-dir 和 :output-to 中的内容。请注意,您必须包含 :protect false 值,否则 lein 将忽略您的添加。

【讨论】:

  • 即使在使用更新的目标运行lein clean 并手动检查所有构建的 JS 是否已消失后,当我尝试编译时仍然会出现分析错误。
  • 如果我创建一个全新的项目然后将现有的 src 文件夹拉入其中,甚至会发生这种情况。这样就可以保证没有缓存的代码搞砸了。
  • 我的建议是同时发布您的完整 project.clj 文件和 state.cljs 文件。我注意到的一件事是我们排除了标准的 clojure 'get' 命令 - 为什么?另一种选择是让你的项目在 github 上可用,也许我可以克隆它,看看你为什么会出错。
  • 我的命名空间暴露了一个不同的 get 方法,不希望它被隐式隐藏。在其他一些人的帮助下,确定了问题并修复了分析器错误。不过感谢您的帮助。
【解决方案2】:

错误最终成为循环依赖,但由于 Clojurescript 1.7.170 中的错误,分析器没有捕获依赖,而是在无限循环中递归分析两个依赖(直到堆栈溢出)。

该错误现已在 master 中修复,但我还是会在此处简要说明它是如何识别的。

  1. 使用standalone Clojurescript compiler 确保工具没有吞咽错误。
  2. 使用{:verbose true} option编译。

查看调试输出开始显示循环依赖:

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

解决循环依赖解决了所有问题,但在 Clojurescript 的未来版本中,您应该会收到编译时分析警告,让您知道您的代码具有循环依赖。

【讨论】:

    猜你喜欢
    • 2019-11-06
    • 1970-01-01
    • 2017-02-13
    • 2016-03-25
    • 2018-09-22
    • 2017-12-26
    • 2017-12-02
    • 2017-11-14
    • 2019-11-07
    相关资源
    最近更新 更多