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

欢迎!有关如何工作的更多信息,请参阅关于页面。

0
ClojureScript

调查 cljs.spec 对 :advanced 构建的影响。

目前所有规范都保存在(私有)cljs.spec/registry-ref 原子中。Closure 编译器不了解这个原子,无法将其作为死代码消除。因此,即使规范在“生产”中未使用,它们仍然会增加生成的JS大小。一些规范可能在运行时使用,无法删除,但是生成部分很可能在 :advanced 构建中永远不会需要,应该以某种方式省略。

在测试构建(使用1.9.93)中,只要在某个地方 :require'd cljs.spec,就会增加11kb(102kb 对 91kb),并且随着每个定义的规范的增加而增长。

11 答案

0

评论者:orestis

在当前 CLJS 版本(1.10.439)中,我观察到带有几个规范(优化后的)javascript 使用60kb--我只是定义规范和fdefs,从未在我的生产代码中使用过spec的s/valid?或类似调用。我的数字来自shadow-cljs报告

cljs/spec/alpha.cljs 35.84 KB
cljs/spec/gen/alpha.cljs 27.33 KB

0

评论者:dnolen

我将指出,这个问题似乎与multimethods非常相似。鉴于规范是一个非常动态的功能,我对解决这个问题没有太大的信心。

0

评论者:greybird

我理解你对多方法(使用全局注册表)的看法,但根据规格,我认为它们可以通过compile-asserts属性设置为false,在不使用valid的情况下完全在构建过程中删除。
(或者类似的东西)。

0
by

评论者:dnolen

Mark,compile-asserts只应用于实际的assert使用。因此,这与规范无关,可能也不太可能如此。

0
by

评论者:greybird

也许可以添加一个新的变量(compile-specs?),以防止规范被添加到注册表中。

我的观点是,如果没有在生产构建中删除规范的方法,我就无法在CLJS中使用规范,因为这对移动应用来说增加了代码体积,而移动应用对体积非常敏感。当然,并非每个人都处于这种状况,但在此情况下,使用规范对测试和调试非常有用。

0
by

评论者:thheller

如果需要,规范可以很容易地完全删除,但如果您想保留一些,那么必须保留所有内容,因为我们无法在编译时知道将使用哪些。

因此,我同意,我们可能无法在这方面做太多。但我们可以试图减少生成代码的数量。鉴于其中一些在运行时立即构建并丢弃。例如,{{cljs.spec.alpha/def-impl}}宏通过代码传递了3个参数。一个是第二个参数{{spec}}的原始代码{{form}}。对于大量规范,{{form}}参数将立即丢弃并且永远不会使用,因为第二个参数{{spec}}会覆盖它。封闭物永远不会删除{{form}},所以我们在宏中可以更聪明一些。

0
by

评论者:greybird

使用新的变量为此目的,或编译器选项,可以满足我的需求。

我发现很难通过将它们放在单独的命名空间中,并调整开发构建,来从生产构建中删除规范,而我无法完全通过这种方式摆脱它们。我怀疑其他人也会发现困难。此外,我与规范的函数之间有较大的距离,并不是我所希望的,我更愿意把它们放在一起。

现在,我只是坚持使用assert。

0

评论者:thheller

Closure Compiler 提供了一些选项,可以通过名称、前缀或后缀从构建中移除代码(链接:1)。我最近将它添加到 shadow-cljs 中(链接:2)。这允许通过以下方式暴力删除所有 spec 的内容

:strip-type-prefixes #{"cljs.spec"}

它只允许完全删除,但如果这是您想要的,效果相当不错。可能应该单独开启一个工单来移植这些选项。

(链接:1) https://shadow-cljs.github.io/docs/UsersGuide.html#_code_stripping
(链接:2) https://github.com/thheller/shadow-cljs/blob/69316cfd0e041ef064696479cd33a65cfd4167d2/src/main/shadow/build/closure.clj#L165-L175

0

评论者:greybird

感谢托马斯。了解这些删除选项很好,我目前正在使用 Shadow。

0

评论者:thheller

请注意,Closure 不喜欢某些模式,并且目前无法完全删除 {{cljs.spec}}。对于像 {{cljs.pprint}} 这样的内容工作正常,但对于 {{defonce}} 生成的代码有问题,这可能需要调整。

0
参考: https://clojure.atlassian.net/browse/CLJS-1701(thheller 报告)
...