【发布时间】:2017-05-27 13:00:55
【问题描述】:
我在 cljc 文件中有以下代码:
(ns proj
#?(:cljs
(:require-macros
[proj :refer [define-project-version]])))
(declare project-version)
#?(:clj
(defmacro define-project-version []
`(def ~'project-version ~(first (drop 2 (read-string (slurp "project.clj")))))))
(define-project-version)
当用于 clj 文件和启动 REPL 时,这确实有效。但是,一旦我制作了一个 uberjar 并尝试运行它,我就会收到关于 project.clj 的异常 - “没有这样的文件或目录”。错误来自 ClojureScript 部分。 uberjar 编译得很好。
为什么代码会尝试加载 project.clj?宏不应该在编译时运行吗?
【问题讨论】:
-
正如我从您提供的代码中看到的那样,您仅为 Clojure 平台(不适用于 ClojureScript)定义了
define-project-version。应该是这样吗? -
define-project-version 是一个宏 - 它不能直接在 ClojureScript 中声明,只能在 Clojure 中声明。因为我使用的是 cljc 文件,所以我只为 Clojure 声明它 - 然后为了在 ClojureScript 中实际使用它,我需要它与 require-macros 一起使用,这仅对 ClojureScript 有效。
-
你不能直接在 uberjar 中 slurp 文件,你必须先将它作为资源加载。
-
我会试试看,但不是在编译时运行宏的全部意义——这意味着当 uberjar 准备好时,这些宏应该已经在它们的位置生成了代码?跨度>
标签: clojure clojurescript leiningen