此请求是在使用通过合格引用递归加载的 Closure 库时抑制分析器的警告。
{code:title=co.edn}
{:libs ["libs/mylib.js"]}
{code:title=libs/mylib.js}
goog.provide('my_lib.core')
my_lib.core = {
add: function(x, y) { return x + y; }
}
{code:title=src/foo/core.cljs}
(ns foo.core
(:require my-lib.core
clojure.set))
以下是说明该概念的示例
$ clj -m cljs.main -co co.edn -re node -r
ClojureScript 1.10.339
cljs.user=> (clojure.set/intersection #{1 2 3} #{2 4 5})
WARNING: 在 <cljs repl> 的第 1 行使用了未声明的 Var clojure.set/intersection
...
cljs.user=> (require 'foo.core)
nil
cljs.user=> (clojure.set/intersection #{1 2 3} #{2 4 5})
#{2}
cljs.user=> (clojure.set/intersection)
WARNING: 在 <cljs repl> 的第 1 行向 clojure.set/intersection 传递了错误的参数数量(0)
cljs.user=> (my-lib.core/add 2 3)
WARNING: 在 <cljs repl> 的第 1 行找不到命名空间:my-lib.core,无法定位 my_lib/core.cljs,my_lib/core.cljc,或提供 "my-lib.core" 的 JavaScript 源文件(请检查使用短横线的命名空间在 ClojureScript 文件名中使用下划线)
WARNING: 在 <cljs repl> 的第 1 行使用了未声明的 Var my-lib.core/add
5
cljs.user=> (in-ns 'foo.core)
nil
foo.core=> (my-lib.core/add 2 3)
5
在上面的示例中,你可以看到当通过合格符号使用递归加载的 ClojureScript 命名空间(在此例中为 {{clojure.set}})时,分析器可以正常工作。
这种特性目前显然不适用于 Closure 库,因此(正确工作的)源代码将需要一个简单的修订,以避免分析器警告(并且源代码需要知道该命名空间是由 Closure 库实现而不是由 ClojureScript 命名空间实现)。
此增强功能的论点是,它导致了一致性,并使得在有效的场景中(即使用递归依赖的情况下)干净地使用 Closure 库成为可能。(通常直接在一个给定的命名空间中表示你的依赖是一个坏主意,但一个可以说可以接受的使用情况是你在使用一个暴露宏的命名空间,这些宏将扩展为使用该命名空间递归加载的代码。这可以发生在使用通过 {{:libs}} 定义的宏或甚至 Closure Library 中的库的宏中。)