问题
在 CLJS (非自托管的) 中,读者字面量在 Clojure 中被求值,但通常必须发出 CLJS,这取决于其他命名空间在运行时的可用性。这限制了 CLJS 中读者字面量的实用性,因为字面量的用户必须了解所有数据读取器实现的要求,并手动在其项目的代码顶部附近包含必要的 requires。
由于读取时与 eval-time 共享相同的运行时,Clojure 和自托管的 CLJS 中发生这种问题的频率较低。他们可以直接需要所需的命名空间,并返回实例而不是代码。
提案
在非自托管的 cljs 中,在依赖树的高处将 data_readers.cljc 和 data_readers.cljs 中提到的命名空间要求添加到依赖树中,以便数据读取器可以满足它们在读取时发出的代码的运行时要求。
具体来说,以下代码应能正常工作
{foo myfoons/foo-reader}
`
(ns myfoons
;; bar 只在 eval 时需要
#?(:cljs (:require bar)))
#?(:clj
;; This is only needed at read time
;; It emits code that requires bar at eval time
(defn foo-reader [x] `(bar/make-bar x)))
`
`
(ns my.app-code)
;; 注意 #foo 的实现需要 bar,
;; 但我们在此处未显式地需要 bar
(def my-foo #foo 123)
`
实施
(link: ~dnolen) 建议将 data_reader-mentioned 命名空间添加到 build pipeline 中的 {{cljs.closure}} 命名空间。
实施问题
- 从 data_readers.cljc 中收集读取器以确定要加载的附加 cljs-time 命名空间时,data_readers.cljc 文件是否应该被求值为 {{:clj}}(与读取器相同,以及 {{cljs.closure/get-data-readers}})或 {{:cljs}}(与自托管相同)?我们应该寻找 {{data_readers.cljs}} 吗?
- 应该将数据读取器映射中提到的命名空间作为“主要”命名空间的依赖项添加,还是应将该标签的命名空间作为依赖项添加到使用该标签的各个命名空间,或者进行其他操作?