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

欢迎!有关详细信息,请访问关于页面。

0
Clojure CLI
编辑

在安装https://github.com/seancorfield/deps-new之后,我使用命令clojure -Tnew app :name clojure-backend创建了一个项目,并遵循了http://pedestal.io/guides/pedestal-with-component的pedestal组件指南。仓库位于:https://github.com/cloped/clojure-backend

我尝试在Cursive上达到与在Leiningen项目中相同的效果,在声明组件启动函数的命名空间上启动REPL并调用它。

阅读nREPL文档https://nrepl.org/nrepl/usage/server.html,Leiningen上有一个:init-ns,这使得这成为可能。

经过在Clojure slack通道https://clojurians.slack.com/archives/C0744GXCJ/p1681750400843819上的几次讨论,以及尝试在Cursive REPL和Clojure CLI中加载所需的命名空间,我们了解到这可能是Clojure CLI的一些功能。

Colin帮我找到了Leiningen中实现这个功能的位置:https://github.com/technomancy/leiningen/blob/24fb93936133bd7fc30c393c127e9e69bb5f2392/src/leiningen/repl.clj#L175-L195

我想知道这是否对Clojure CLI有意义。如果是的话,我很高兴帮助实现它,开始我对Clojure社区的贡献。

2 答案

+1

被选中
 
最佳答案

在启动REPL时,不需要将代码引入任何工具以切换命名空间。

定义自定义 user 命名空间 是一种长期以来应用于开发中管理组件生命周期(启动、停止、重启)的方法,它不依赖于编辑器、工具或组件库,即它与所有工具兼容。

在项目中创建一个 dev/user.clj 文件,该文件定义了一个 user 命名空间。在REPL启动期间,除非代码在 comment 形式中,否则这个命名空间中的代码会被加载。

REPL从 user 命名空间开始,因此在 dev/user.clj 中定义的函数无需切换到不同的命名空间或使用完全限定名即可立即使用。

在自定义的 dev/user.clj user 命名空间中定义管理组件的函数,它们可以立即在REPL使用的默认命名空间中使用。

这种方法的附加好处是代码更干净,并且开发支持代码与生产代码之间有明确的分离。

可以通过Clojure CLI别名包含类似component repl和integrant repl之类的库,这样就不会给CI工作流程和生成的部署uberjar增加重量。

自定义的 user 命名空间包含了组件repl(或其他开发时组件库,如Integrant REPL)的require语句。

我个人使用这种方法启动一系列开发工具,无论它是Leiningen还是Clojure CLI项目。

Practicalli自定义REPL启动详细介绍了通用方法

Practicalli REPL Reloaded详细介绍了我使用的特定开发工具(portal,hotload,命名空间重新加载,事件日志等)

Practicalli项目模板为seancorfield/deps-new提供了包含自定义的 dev/user.clj user 命名空间的顶级模板,包含Integrant REPL示例(与aero集成)

+1

您可以将-e与其他“main opts”命令行选项结合起来,以在特定命名空间中启动

> cat src/my_proj/api.clj
(ns my-proj.api)

(defn foo [opts]
  (println (get opts :bar "No :bar passed!")))

> clj -M -e "(require 'my-proj.api)(in-ns 'my-proj.api)" -r
#object[clojure.lang.Namespace 0x7957dc72 "my-proj.api"]
my-proj.api=>
它对我不起作用。我得到了以下内容


➜  clojure-backend git:(main) ✗  clj -r -e "(require 'clojure-backend.core) (in-ns 'clojure-backend.core)"
警告:使用选项隐式使用clojure.main已被弃用,请使用-M
你好
在in-ns之后
Clojure 1.11.1
user=> *ns*
#object[clojure.lang.Namespace 0x68dcfd52 "user"]
user=> (my-function)
语法错误,在(REPL:1:1)编译
无法在此上下文中解析符号:my-function
user=>
我想出来了。我在-e命令之前输入了-r,所以它不起作用 :D
仍在思考这个问题,而不是收到的参数,难道不应该是一个加载和更改命名空间的代码?
一般来说,Clojure 采用小、简单、可组合的方法。Leiningen 提供了很多旋钮和开关,旨在使事情“简单”。通过添加额外参数,这使得实现这一点变得简单,但代价是牺牲了小、简单和可组合性。" -e 选项允许您运行任何代码,包括解决您提出的问题。
...