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

欢迎!请参阅 关于 页面以了解更多关于这个工作方式的信息。

0
Clojure CLI
编辑

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

我正在努力实现我在 Leiningen 项目中曾经做过的事情,在 Cursive 上启动我的 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时切换命名空间不需要将代码引入任何工具。

通过定义自定义的用户命名空间(如_leiningen_中的操作)是管理组件生命周期(启动、停止、重启)的一种长期存在的开发方法,它不受编辑器、工具或组件库的依赖,即它可以与任何东西一起工作。

在项目中创建一个dev/user.clj文件,定义一个user命名空间。除非是注释形式,否则该命名空间中的代码在REPL启动时加载。

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

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

这种方法的好处是代码更清晰,开发支持代码与生产代码之间的分离更明确。

可以通过Clojure CLI别名包括组件REPL和integrant-repl之类的库,这样它们就不会增加CI工作流程和最终部署的uberjar的重量。

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

我个人使用这种方法启动各种支持开发工具(无论是否为_leiningen_或Clojure CLI项目)。

Practicalli Custom REPL Startup 详细说明了通用方法

Practicalli REPL Reloaded 详细说明了我使用的特定开发工具(portal、hotload、命名空间重新加载、事件记录等)

Practicalli Project Templates 为seancorfield/deps-new提供生产级模板,其中包括一个自定义的user命名空间、包含aero的practicalli/service模板的Integrant REPL示例

+1

您可以将-e与命令行上的其他"主选项"结合起来以在特定命名空间中启动

> 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 选项允许您运行任何代码,包括解决您提出的问题。
...