作为依赖项的Clojure

2020-05-04 16:13:44

我有一个非常可耻的坦白要做:我可能长期以来忽视了一个我应该维护的开源库,clj-tagSoup。

这本来不是什么大问题,但这是我在GitHub上第二受欢迎的项目。诚然,我可能不再觉得有必要这样做了,但显然人们会这样做。我真希望我花了一些时间来审查和合并即将到来的PR。

无论如何,我最近被提示要重新启动它,我正在准备一个新的版本。在它上面,我一直在更新依赖项以更新它们的最新版本,当看到project.clj中对[org.clojure/clojure";1.2.0";]的依赖项时(是的,它已经被忽略了那么长时间),我开始想:应该依赖哪个Clojure呢?实际上,Clojure本身是否应该是一个真正的依赖呢?

我在谷歌上到处寻找最佳实践,但没有得到确凿的答案。所以我开始做一些研究。

TLDR:使用Leiningen,添加:Scope";Provided";;with cli-tools,您不必这样做,除非您想要更明确。

Clojure项目有可能完全不声明对Clojure的依赖吗?

显然,这只对图书馆有意义。或者,更广泛地说,用于那些不打算独立使用的项目,而是包含在其他项目中的项目(这些项目将具有自己的Clojure依赖项)。

那么Leiningen(从2.9.3版开始,但我猜旧版本的行为类似)将不允许您直接启动新的REPL:

$lein replError:无法找到或加载主类clojure.mainCause By:java.lang.ClassNotFoundException:clojure.mainSubprocess失败(退出代码:1)。

但是,并不是所有的东西都丢失了:lein jar工作得很好(只要您没有对任何名称空间进行AOT编译),lein install也是如此。由此产生的库将很高兴地充当其他项目的主要依赖项。

不依赖特定Clojure版本的好处是您不会将其强加给您的消费者。如果一个JAR库依赖于Clojure 1.9.0,但是一个使用它的应用项目依赖于Clojure 1.10.1,那么Leiningen将获取1.9.0的pom.xml(它足够聪明,能够计算出不需要JAR本身,因为冲突总是以直接依赖的方式解决),并且lein deps:tree将报告“可能令人困惑的依赖关系”。

不过,拥有一个不能对其发起新的REPL的资源库并不是很有用。所以有些人所做的就是声明对Clojure的依赖,而不是主要的依赖关系:依赖关系,而是在一个简单的配置文件中。

这避免了冲突,并重新带来了推出新的REPL的可能性。有时,人们会为不同的Clojure版本创建多个概要文件;Leiningen的文档提到了这种可能性。

不幸的是,使用这种方法仍然不可能使用Leiningen进行AOT编译或创建uberjar。(将Clojure放在:Provided配置文件中会导致构建uberjar不会成功,但生成的独立JAR实际上并不包含Clojure)。

另一种选择是将Clojure添加到main:依赖项中,但是提供了:Scope";。根据Maven文档,这意味着:

这与编译非常相似,但表示您希望JDK或容器在运行时提供依赖项。例如,在为Java Enterprise Edition构建Web应用程序时,您可以将对Servlet API和相关Java EE API的依赖性设置为所提供的范围,因为Web容器提供了这些类。此作用域仅在编译和测试类路径上可用,并且不可传递。

关键是最后几句话:“不可传递性。”如果项目A依赖于声明了一个“提供的”依赖项C的程序库B,那么C将不会自动放入A的依赖项中,预计A将不会显式声明自己的C。

这意味着,当涉及到声明一个Clojure依赖项时,它对于库和独立项目都是足够的。它不会破坏任何东西,不会导致任何短暂的冲突,并且可以在需要多个配置时与配置文件方法结合使用。

CLI-Tools将接受像{}这样简单的Deps.edn。即使将-Srepro传递给Clojure或CLJ(它排除了您的~/.clojure/dess.edn中可能存在的Clojure依赖项)也不会破坏任何东西:cli-tools将只使用1.10.1(至少从1.10.1.536版本开始)。

使用cli-tools,作为一个类库作者,您可能根本不需要声明一个Clojure依赖项。但这片土地的情况不如雷宁根的统一(例如,有相当多的Uberjarer可供选择),所以先检查一下你的工具是合理的。

我不再是一名Boot用户,所以我现在也不能说。但据我所知,它和Leiningen和Maven一样使用乙醚,所以我敢打赌,同样的警告也适用于Leiningen。不过,我还没检查过。

我想这将是一项非常有趣的研究,来研究受欢迎的项目是如何依赖(或不依赖)Clojure的。我向GitHub的API查询了1000个最受欢迎的Clojure项目,获取并解析了它们的project.cljs和/或dess.edn,然后进行了统计。

我会写一封信