我的理解是,一个命名空间必须自己 {{:require-macros}} 才能使其宏自动可访问,但这一点现在似乎不再准确。
给定的这个最小例子:
;; src/demo/lib.cljs
(ns demo.lib)
;; src/demo/lib.clj
(ns demo.lib)
(defmacro foo [& args]
`(prn ::macro))
;; src/demo/test.cljs
(ns demo.test
(:require [demo.lib :as lib]))
(lib/foo 1 2 3)
我原本期望对于 {{lib/foo}} 有警告,因为 {{demo.lib}} 没有为它的宏声明 {{:require-macros}},而 {{demo.test}} 也没有使用 {{:include-macros}} 或 {{:refer-macros}}。
通过构建API编译确实产生了预期的警告,但前提是 {{demo.lib}} 的 CLJ 命名空间没有被其他地方所引用。
警告:使用了未声明的变量 demo.lib/foo,位于 src/demo/test.cljs 第5行
;; build.clj
(require '[cljs.build.api :as cljs])
;; (require 'demo.lib) ;; 在这里引用它将移除警告
(cljs/build
"src"
{:output-dir "out"
:optimizations :none
:verbose true})
在 build.clj 中启用 {{(require 'demo.lib)}} 可使警告消失,代码也正确使用宏。
一些流行的库(例如 devcards)没有自我引用,但如果宏文件至少在其他地方被引用了也能正常工作。
这是预期的行为,还是偶然的?