Hi, are there any sample repos showing how to use Duct with deps.edn instead of Leiningen?
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
Simple answer is, if you’re willing to sacrifice uberjars/aot it’s easy
@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=> (dev)
:loaded
dev=> (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
Looks like it can't find the duct/module.logging
dependency
yeah or maybe ig/load-namespaces
hasn’t been called?!
I’m sorry, that was a silly issue, I confused duct/logger with duct/module.logging :man-facepalming: It works now
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?
as far as I know the second of those is just re-establishing the default leiningen prep-tasks for the :repl
profile
though last time I looked at this was probably 2 years ago
as far as I know also that key is only relevant if you want to manage your clojurescript compilation with duct
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.
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
(we use shadow)
I personally use https://github.com/g7s/module.shadow-cljs
But you could also use shadow-cljs separately from duct
what’s the benefit to using that?
I just like having everything build in a single process. But I don't use deps.edn
yeah ok fair enough
And you should be able to switch between Clojure / Clojurescript repls
But I haven't gotten that to work yet
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:
I could probably use that for other things in our app
Yeah I'd like to create a :duct/compiler
key to compile our CSS as well
Basically have a single build system
Not sure duct makes a good build system though… though neither does tools.deps, yet 🙂
though simple stuff like that should work fine
How I crave a "good" build tool for clojure
yeah same
🤞 for tools.build
Would be nice
Hopefully it won't be in alpha for 3 years 😛
🙏
And I just hope it'll be more intuitive, unlike weird -A:
-X:
flags. But maybe that's just my preference
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…
I certainly miss some bits of lein, but other aspects of tools.deps are great
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)
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?
For me I like the separation of code and data
-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
but I agree it’s a bit confusing, as stuff has changed a bit recently
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.