我想创建一个leiningen应用程序的uberjar。我的配置是:
:uberjar {:omit-source true
:aot :all
:uberjar-name "myapp.jar"
:source-paths ["env/prod/clj" ]
:resource-paths ["env/prod/resources"]}
但在执行lein uberjar
时,我发现项目中的文件正在被编译,但编译被困在包含大部分代码的文件上,持续了十分钟,而且还在继续。此文件包含的行数不超过140行。
TL;DR:从不def
副作用
如评论所述:
。。。我只是觉得这行:
(defonce server (http/start-server server-handler {:port 8982}))
引起了挂起。
不要把这样的东西放在顶层。
defonce
只意味着一旦它在那里就不会被重新定义(所以在这种情况下它将阻止一些";端口已在使用中";重新加载时出错。
摆脱困境的方法
编写一个函数,启动此服务器。然后从你的主菜单上调用它。对于在开发过程中,您可以从REPL运行该函数,也可以添加一些在用户ns中重新加载/重新启动逻辑。
另一种选择可能是使用delay
:它只会在获得deref
后执行代码。
";资源绑定";你必须处理的,越是一些系统方法将为您的应用程序提供更好的结构。例如,看看:
- 编织者/整合者
- stuartsierra/组件
- 托利乌斯
那么,为什么在def
中放置阻断物或副作用会有问题呢
Clojure编译器的工作方式实际上是";运行";代码。所以compile
基本上是:
- 启用生成字节码并将其写成.class文件
- 加载名称空间;运行";它
这意味着,在编译时,将执行顶级副作用。对于def
中的阻塞操作,将阻塞编译(这相当于显而易见(,否则您的CI服务器将无法编译,因为它无法连接到数据库等
Clojure中代码生成工作原理的一个很好的解释:
- 所有这些类文件都是关于什么的?和其他故事-加里·弗雷德里克斯