duct

2021-01-25T16:12:04.004700Z

Hi, are there any sample repos showing how to use Duct with deps.edn instead of Leiningen?

kwrooijen 2021-01-25T16:13:19.004800Z

@rickmoynihan

2021-01-25T16:28:03.005Z

None that are public that I know of… though it’s pretty straightforward. See this issue for some hints: https://github.com/duct-framework/duct/issues/92

2021-01-25T16:28:59.005300Z

Simple answer is, if you’re willing to sacrifice uberjars/aot it’s easy

2021-01-25T16:44:32.005500Z

@rickmoynihan Thanks for pointing the thread. Actually at the point where I am, I’m trying to successfully use only REPL and (integrant.repl/go). But it fails:

% clj -Mdev:repl                                                                                                                                                                                                                                                                                                                                                    nREPL server started on port 62879 on host localhost - <nrepl://localhost:62879>
[Rebel readline] Type :repl/help for online help info
user=&gt; (dev)
:loaded
dev=&gt; (go)
Execution error (IllegalArgumentException) at integrant.core/try-build-action (core.cljc:294).
No method in multimethod 'init-key' for dispatch value: :duct.module/logging

kwrooijen 2021-01-25T16:46:22.005900Z

Looks like it can't find the duct/module.logging dependency

👍 1
2021-01-25T16:46:44.006100Z

yeah or maybe ig/load-namespaces hasn’t been called?!

2021-01-25T16:48:37.006400Z

I’m sorry, that was a silly issue, I confused duct/logger with duct/module.logging :man-facepalming: It works now

👍 1
2021-01-25T17:02:02.006800Z

I noticed that in lein duct project template, https://github.com/duct-framework/duct/commits?author=weavejester specifed two :prep-tasks, including one for :repl. Should I provide any equivalent of that :prep-tasks for running the app in REPL?

2021-01-25T17:04:30.007200Z

as far as I know the second of those is just re-establishing the default leiningen prep-tasks for the :repl profile

2021-01-25T17:04:46.007400Z

though last time I looked at this was probably 2 years ago

2021-01-25T17:09:36.007600Z

as far as I know also that key is only relevant if you want to manage your clojurescript compilation with duct

👍 1
2021-01-25T17:10:31.007900Z

I’ve often wondered if duct uses it to aot clojure; though based upon ns dependencies… Though I’ve never seen any code in duct that did that.

2021-01-25T17:13:05.008100Z

FYI: I don’t think you should use the duct machinery for clojurescript… it’s pretty outdated. You’d probably be better using shadow-cljs, or something else

2021-01-25T17:13:15.008300Z

(we use shadow)

👍 1
kwrooijen 2021-01-25T17:14:58.008500Z

I personally use https://github.com/g7s/module.shadow-cljs

👍 1
kwrooijen 2021-01-25T17:15:27.008900Z

But you could also use shadow-cljs separately from duct

2021-01-25T17:16:32.009100Z

what’s the benefit to using that?

kwrooijen 2021-01-25T17:16:48.009300Z

I just like having everything build in a single process. But I don't use deps.edn

2021-01-25T17:17:04.009500Z

yeah ok fair enough

kwrooijen 2021-01-25T17:17:24.009700Z

And you should be able to switch between Clojure / Clojurescript repls

kwrooijen 2021-01-25T17:17:31.009900Z

But I haven't gotten that to work yet

2021-01-25T17:19:47.010100Z

I wasn’t aware of the duct shadow module I just use shadow standalone, can switch between repls etc. but yeah it’s a separate process. I guess the interesting thing about the :duct/compiler key is that it isn’t included in the app at runtime :thinking_face:

2021-01-25T17:20:22.010400Z

I could probably use that for other things in our app

kwrooijen 2021-01-25T17:20:53.010700Z

Yeah I'd like to create a :duct/compiler key to compile our CSS as well

kwrooijen 2021-01-25T17:21:08.010900Z

Basically have a single build system

2021-01-25T17:21:33.011100Z

Not sure duct makes a good build system though… though neither does tools.deps, yet 🙂

2021-01-25T17:22:36.011300Z

though simple stuff like that should work fine

kwrooijen 2021-01-25T17:22:41.011500Z

How I crave a "good" build tool for clojure

2021-01-25T17:22:49.011800Z

yeah same

2021-01-25T17:23:07.012Z

🤞 for tools.build

kwrooijen 2021-01-25T17:23:14.012200Z

Would be nice

kwrooijen 2021-01-25T17:23:25.012400Z

Hopefully it won't be in alpha for 3 years 😛

2021-01-25T17:23:36.012600Z

🙏

kwrooijen 2021-01-25T17:24:09.012800Z

And I just hope it'll be more intuitive, unlike weird -A: -X: flags. But maybe that's just my preference

2021-01-25T17:29:03.013Z

tbh I find the tools.deps flags work really well… They definitely make trade offs on various things (like standardisation) in favour of fine grained control, but they’re very flexible. It’s not a build system though; and it’s not trying to be. I hear tools.build leverages the :exec-args stuff quite a bit though, so we’ll see…

2021-01-25T17:29:34.013200Z

I certainly miss some bits of lein, but other aspects of tools.deps are great

kwrooijen 2021-01-25T17:39:42.013400Z

I definitely like the aliases as well. But I'd much rather see (for example) clj run new ... instead of clj -X:new ... (or -A: I'm honestly not sure which one to use)

2021-01-25T17:46:01.016900Z

In the past I used to use integrant and I kinda liked config specified within clj files. With a namespaced keywords they were more readable compare to fully qualified keywords needed for edn. What is the advantage of using configs within edns vs in clj file?

kwrooijen 2021-01-25T17:47:09.017300Z

For me I like the separation of code and data

👍 1
2021-01-25T18:13:02.018100Z

-A is for repl invocation -X is for function eXecution -M is for Main execution Essentially -A generically provides classpath options :extra-deps and args data. -X specifies the alias that contains the :exec-fn to use (only one :exec-fn can be picked). -M similar for specifying a main namespace

2021-01-25T18:13:58.018300Z

but I agree it’s a bit confusing, as stuff has changed a bit recently

2021-01-25T18:17:00.020500Z

Also if you use edn with ig/load-namespaces your require tree between components isn’t hardcoded into your app. Each component defines a subtree of requires; but the actual app is dynamically assembled out of components. Unused components aren’t loaded etc. Many configurations can be supported at once, with only the required components being loaded.