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时切换命名空间不需要将代码引入任何工具。

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

在项目中使用 dev/user.clj 文件定义一个 user 命名空间。除非以 形式存在,否则此命名空间中的代码将在REPL启动时加载。

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重新加载 说明了我所使用的特定开发工具(portal,hotload,命名空间重载,事件记录等)

Practicalli项目模板 为seancorfield/deps-new提供了生产级别的模板,这些模板包括自定义的 dev/user.clj user 命名空间,以及包含aero的 practicalli/service 模板示例

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