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 REPL 中不会出现这种情况。

7 个答案

0

评论者:mfikes

问题在于浏览器对资源的调用是异步的(至少在 REPL 中是这样),因此设置全局导出的代码与加载的 require 代码之间存在竞争。

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

0

评论者:mfikes

CLJS-2854-1.patch 引入了一种机制,REPL 可以表明它们是否有排队加载后活动的机制,并且浏览器 REPL 参与了这个机制。使用的名称可以清理,特别是如果这导致公共 API,REPL 可以使用。

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}},但那将是一个异步加载,所以不会工作。这不会影响可传递的情况。

0

评论者:mfikes

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

0

评论者:mfikes

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

0
...