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

欢迎!请参阅 关于页面 了解更多关于这个平台的信息。

0
ClojureScript

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

目前所有规范都保存在 (私有) cljs.spec/registry-ref 原子中。该原子不被 Closure Compiler 所理解,无法将其视为废代码而消除。因此,即使规范在 "生产" 中未被使用,它们仍然会增加生成的 JS 大小。一些规范可能在运行时使用,并且不能被删除,但是生成的部分在 :advanced 构建 中可能根本不需要,应该以某种方式省略。

在一个测试构建(1.9.93)中,只要在某个地方 :require'd cljs.spec,它就会增加 11kb(102kb 对 91kb),并且每个定义的规范都会相应增加。

11 答案

0

评论者:orestis

在当前的 CLJS 版本(1.10.439)中,我注意到只有几个规范,我使用了 60kb 的 (优化后的) JavaScript。我只是在定义规范和 fdefs,绝不在我的生产代码中使用来自 spec 的任何 s/valid? 或类似的调用。我使用的数字来自 shadow-cljs 报告。

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

0

评论者:dnolen

我将指出,这个问题似乎非常类似于多重方法。鉴于规范是一个非常动态的特性,我对如何处理这个问题持有怀疑态度。

0

评论者:greybird

我明白你在多方法(全局注册表的使用)方面的话,但我觉得如果设置了 compile-asserts 为 false,即可在未使用 s/valid 时将 spec 完全移除。
(或类似的选项)。

0

评论者:dnolen

马克,compile-asserts 仅应用于实际的 assert 使用。所以这与 spec 没有关系,而且可能不太可能。

0

评论者:greybird

可能可以添加一个新的变量(编译 spec?),以防止 spec 被添加到注册表中。

我认为,在 CLJS 中使用 spec 将需要在生产构建中删除它们的一种方法,因为对移动应用来说,增加的代码量很大,而这些应用非常关注代码大小。当然,并不是每个人都处于这种情况,但是在这种情况下使用 spec 对测试和开发时的调试非常有好处。

0

评论者:thheller

如果需要,spec 容易完全删除,问题在于,如果你要保留一些 spec,你必须保留所有 spec,因为我们无法在编译时确定将使用哪些。

因此,我同意我们可能无法在这方面做很多事情。我们可能可以减少生成的代码量。考虑到其中一些代码是构建后立即丢弃的。例如,{{cljs.spec.alpha/def-impl}} 通过宏代码传递了 3 个参数。一个是第二个 {{spec}} 参数的 {{form}}。对于大量 spec,{{form}} 参数将立即丢弃,并且永远不会使用,因为第二个 {{spec}} 参数取代了它。然而,Closure 不会删除 {{form}},所以我们可以在宏中更聪明地处理这一点。

0

评论者:greybird

使用新的变量或编译选项完全删除 spec 将满足我的需求。

我发现很难通过将它们放入单独的命名空间并配置开发构建来从生产构建中删除 spec,而且我没有能够完全通过这种方式消除它们。我怀疑其他人也会觉得这样做很难。此外,对于我来说,spec 与其函数之间有大距离是非常不希望的,我更愿意把它们放在一起。

目前我只是在坚持使用 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

感谢 Thomas。了解有关剥离选项是很不错的,我现在正在使用 Shadow。

0

评论者:thheller

请注意,Closure 不喜欢某些模式,并且当前无法完全剥离 {{cljs.spec}}。它对像 {{cljs.pprint}} 这样的东西工作得很好,但与 {{defonce}} 生成的代码有问题,所以可能需要调整。

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