请在2024年Clojure现状调查!中发表您的看法。

欢迎!请参阅关于页面了解更多该网站的工作方式。

+1
ClojureScript
命名空间在运行时加载的顺序与用户代码中命名空间被require的顺序无关。这似乎影响所有优化级。这意味着开发者不能依赖于在特定命名空间中运行副作用代码,在依赖于副作用的其他命名空间加载之前。

复制步骤

运行以下命令:


clj --main cljs.main --compile-opts '{:target :nodejs :main a}' --compile a


将会编译在
在编译后,请注意以下内容:

输出文件out/cljs_deps.js中,针对a.js的goog.addDependency调用包含其依赖项的任意顺序。例如,在我的机器上运行的结果是:


goog.addDependency("../a.js", ['a'], ['cljs.core', 'e', 'c', 'g', 'b', 'd', 'f']);


用{{node out/main.js}}运行编译后的代码时给出的控制台输出表明,运行时的加载顺序与out/cljs_deps.js中反映的顺序相同


e的主体

c的主体

g的主体

b的主体

d的主体

f的主体


分析

看起来[CLJS-1453](
https://dev.clojure.org/jira/browse/CLJS-1453)中做了一些工作来确保编译时保持顺序,但似乎到Rio greedy time被emit时,顺序可能会出现问题。

似乎给定ClojureScript文件的输出最终由cljs.compiler/emit-source的输出确定。那里删除了与CLJS-1453前Ana的方法中'ns'解析方法相同的依赖项。

附加的补丁解决了我的狭义用例中的问题,但我认为基函数传递了`:uses`和`:requires`作为映射,因此可能需要更多工作才能完全解决。

11答案

0

评论由:chancerussell 做出

对于在票据中插入标记感到抱歉——我本以为在提交后可以清理。

0

评论由:mfikes 做出

CLJS-3056.patch 通过了 CI 和 Canary (/)

0

评论由:thheller 做出

附带的补丁仍然使用 {{deps}} 映射,它将只维护插入顺序,直到达到数组-映射阈值,一旦开始使用哈希映射,事情将不再有序。在 shadow-cljs 中,我通过维护一个附加的 {{:deps}} 矢量来处理这个问题,而不仅仅是通常的 {{:requires}} 映射。

0
评论由:chancerussell

这可能是最合适的解决方案——我不想尝试修改现有代码中映射的类型。

我今晚会看看这个问题——CLJS-1453 的补丁可能也存在相同的问题。

话说回来,我想知道当 ns 表达式同时包含 :require 和 :use 时,排序的语义应该是什么?很明显,前一种代码中保证排序不可行,但我想确保这一点。
0

评论由:thheller 做出

看起来分析器解析 'ns 和 'ns** 时已经维护了一个 {{:deps}} 矢量。只需要在 cljs.compiler/emit-source 函数中使用它,而不是使用 requires/uses 映射的值。

0

评论由:chancerussell 做出

托马斯是对的,确实存在一个 {{:deps}} 矢量,并且处于预期顺序,所以我已提交一个新的补丁,使用该矢量。

一个问题——当 {{cljs.core}} 和 {{cljs.core.constants}} 都存在时,它们的顺序应该是什么?显然,前一种代码中排序没有保证,但我想确保这一点。

(似乎测试 test-cljs-1882-constants-table-is-sorted 告示 cljs.core 应该先出现。)

0

评论由:mfikes 做出

2019年3月24日12:58 PM 的CLJS-3056.patch通过了CI和Canary测试(/)

0

由dnolen发表的评论:

{{cljs.core}}必须在{{cljs.core.constants}}之前,因为没有定义关键字结构,{{cljs.core.constants}}将无法工作。根据情况,排序是绝对有保证的,否则我们会听到很多关于高级构建失败的投诉。

0

评论由:chancerussell 做出

David,当你说“排序绝对有保证”时,你是指仅仅{{cljs.core}}和{{cljs.core.constants}},还是整体的依赖项?当前的代码正在将元素{{conj}}到集合中,这并不保证能保持任何排序,据我所知。

0

评论由:mfikes 做出

哎呀,我搞错了:CLJS-3056.patch在Windows CI(x)中失败

这特别会导致{{cljs-2077-test-loader}}堆栈溢出

ERROR在(cljs-2077-test-loader)(core.clj:6077)

CI构建: https://ci.appveyor.com/project/mfikes/clojurescript/builds/24478525

0
参考:https://clojure.atlassian.net/browse/CLJS-3056(由chancerussell报告)
...