2024 Clojure状态调查! 中分享您的想法。

欢迎!请查阅 关于 页面,了解更多关于如何使用本站的信息。

0
ClojureScript
{code:title=mylib.js}
mylib = { abc: 3 }


{code:title=co.edn}
{:foreign-libs [{:file "mylib.js"
                 :provides ["my-lib"]
                 :global-exports {my-lib mylib}}]}


重现


$ clj -m cljs.main -co co.edn -r
ClojureScript 1.10.339
cljs.user=> (require 'my-lib)

cljs.user=> my-lib/abc
TypeError: Cannot read property 'abc' of undefined
     (<NO_SOURCE_FILE>)
cljs.user=> (require 'my-lib)

cljs.user=> my-lib/abc
3


这种情况在 Node 和 Nashorn REPLs 中不会发生。

7 个答案

0

评论者:mfikes

问题在于浏览器要求的异步性(至少在 REPL 中是如此),因此设置全局出口的代码与加载要求的代码存在竞争关系。

CLJS-2854-0.patch 通过条件排队代码(当在浏览器 REPL 中时)并在加载队列排空后执行它,探索解决这个问题的方式(尚未包括测试等)。

0

评论者:mfikes

CLJS-2854-1.patch 引入了一种机制,其中 REPL 可以指示它们是否有排队后加载活动的机制,并使浏览器 REPL 参与此机制。使用的名称可以简化,特别是如果这导致了可供 REPL 使用的公共 API。

0

评论者:mfikes

使用此代码

`
(ns foo.core
(:require my-lib))

(def x my-lib/abc)
`

补丁后工作正常

`
$ clj -m cljs.main -co co.edn -r
cljs.user=> (require 'foo.core)

cljs.user=> foo.core/x
3
`

0

评论者:dnolen

为澄清问题——REPL中的{{(require ...)}}形式默认在{{cljs.user}}中,这意味着直接引用带有全局输出的库将与该库的{{goog.require}}竞争,因为在{{goog.require}}之后马上就是该库的输出映射,但是这将是异步加载,所以不起作用。这不会影响不可传递的情况。

0

评论者:mfikes

CLJS-2854-2.patch试图通过简单地使用超时来避免竞争来保持编译器代码中的逻辑。

0

评论者:mfikes

CLJS-2854-2.patch不再适用。

0
...