莱恩·尤伯贾永远都在接受



我想创建一个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基本上是:

  1. 启用生成字节码并将其写成.class文件
  2. 加载名称空间;运行";它

这意味着,在编译时,将执行顶级副作用。对于def中的阻塞操作,将阻塞编译(这相当于显而易见(,否则您的CI服务器将无法编译,因为它无法连接到数据库等

Clojure中代码生成工作原理的一个很好的解释:

  • 所有这些类文件都是关于什么的?和其他故事-加里·弗雷德里克斯

最新更新