ClojureScript编译器无法在同一目录中找到命名空间/文件。

6

lein cljsbuild在找不到一个与另一个命名空间/文件定义的文件时会出现问题,除非我确保它们按照一定的顺序编译。

我的目录结构如下:

project/
  project.clj
  src/
    cljs/
      contempo/
        common/
          defs.cljs
        view/
          core.cljs
          navigation.cljs

navigation.cljs有一些用于构建Om组件以在页面上导航的内容,而core.cljs则是此特定页面的主要入口点。navigation.cljs从以下内容开始:

(ns contempo.view.navigation (:require ...))

core.cljs 以以下内容开始:

(ns contempo.view.core (:require [contempo.view.navigation :as navigation]))

当我运行lein cljsbuild时,会得到以下结果:

solace:Groov jfischer$ lein cljsbuild auto
Compiling ClojureScript.
Compiling "war/view/js/app.js" from ["src/cljs/contempo/common" "src/cljs/contempo/view"]...
Compiling "war/view/js/app.js" failed.
clojure.lang.ExceptionInfo: failed compiling file:src/cljs/contempo/view/core.cljs

... snipped stacktrace ...

Caused by: clojure.lang.ExceptionInfo: No such namespace: contempo.view.navigation at line 1 src/cljs/contempo/view/core.cljs

如果我从 core.cljs 中删除所有与 contempo.view.navigation 相关的引用,运行 lein cljsbuild auto 并等待编译完成,然后再放回去并保存(以便 cljsbuild 捕捉到更改),那么它就能正常工作。但这很愚蠢,不应该是必要的。

我的 project.clj 如下:

(defproject contempo "0.0.0-SNAPSHOT"
  :description "Experimenting with ClojureScript and Om"
  :dependencies [[org.clojure/clojure "1.6.0"]
                 [org.clojure/clojurescript "0.0-2740"]
                 [org.clojure/core.async "0.1.346.0-17112a-alpha"]
                 [org.omcljs/om "0.8.7"]]

  :plugins [[lein-cljsbuild "1.0.4"]]

  :clean-targets ^{:protect false} ["war/view/js/app.js"
                                    "war/view/js/out"]

  :cljsbuild {:builds [{:id "view-dev"
                        :source-paths ["src/cljs/contempo/common"
                                       "src/cljs/contempo/view"]
                        :compiler {:output-to "war/view/js/app.js"
                                   :output-dir "war/view/js/out"
                                   :optimizations :none
                                   :cache-analysis true
                                   :source-map true}}]})

有什么明显的错误吗?这看起来与我看过的每个ClojureScript项目非常相似。
更新:展示错误的小型框架项目可以在此处找到:namespace-error-demo.zip

没有错误或警告,对我来说是可以工作的。我怀疑你可能有循环依赖关系,或者其中一个源文件无法编译。另外,尝试使用单个源路径“src/cljs/contempo/”也许值得一试。 - Jarlax
检查了循环依赖项,将其折叠成一个源路径,并实际删除了几乎所有的代码,但仍然出现错误。可在此处获得演示它的微型项目:namespace-error-demo.zip - Jonathan
1
我刚刚下载并编译了演示程序,没有遇到任何问题。尝试使用 lein clean 命令清理一下。如果这不起作用,请前往您的 ~/.m2/ 目录并删除您的 Clojurescript 和 Clojure 依赖项,它们可能处于错误状态。 - sbensu
2个回答

6
问题出在:我没有遵守命名空间解析规则。
使用源路径为 src/cljs/contempo/commonsrc/cljs/contempo/view,如果我要求 contempo.view.whatever 命名空间,编译器将会在 src/cljs/contempo/common/contempo/view/whatever.cljssrc/cljs/contempo/view/contempo/view/whatever.cljs 中查找。
我必须使用 src/cljs 作为源目录。我想实现的(省略了不需要的页面代码)有点傻(因为它仍然会拉取所有的 ClojureScript),现在通过 ClojureScript 中正确的 Google Closure 模块支持得到了恰当的解决。请参考:ClojureScript中Google Closure模块支持

4
我今天也遇到了同样的问题。在我的情况下,根本原因是文件名中带有“-”的.cljs文件。我只是在切换到0.0-3030后才发现这是问题所在,因为更高版本的cljs编译器遵循严格的文件路径和命名空间约定,提供了更好的错误消息。
你可以尝试将`:source-paths`更改为`["src/cljs"]`。

非常感谢!我遇到了完全相同的问题,没有你的评论我就无法解决它! - Victor Marchuk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接