This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2016-11-13
Channels
- # beginners (43)
- # boot (318)
- # cider (1)
- # cljs-dev (6)
- # clojure (30)
- # clojure-brasil (2)
- # clojure-korea (2)
- # clojure-russia (31)
- # clojure-spec (13)
- # clojure-uk (7)
- # clojurebridge (1)
- # clojurescript (17)
- # code-reviews (1)
- # cursive (2)
- # data-science (1)
- # datascript (10)
- # hoplon (116)
- # javascript (2)
- # juxt (1)
- # mount (2)
- # onyx (12)
- # parinfer (2)
- # pedestal (1)
- # protorepl (1)
- # re-frame (3)
- # ring (1)
- # untangled (1)
It seems like the recommended way to serve static generated files is with boot-http
. Does that mean that I don't use my web server component at all in development?
@zane hi! it's just convenient, because if you have only client code and while development you just plug (serve)
and have web-server for static files out of the box
yes, according to this: https://github.com/adzerk-oss/boot-cljs/wiki/Serving-files
@zane yes, should be available on classpath. Location is defined by your *.cljs.edn file (assuming you have one) — if you don't create one as described in the "Multiple Builds" section in the "Usage" page on the wiki
Writing a boot task to ass :exclusions
for me when there are conflicts.
Where can I find helper functions available in boot to manipulate the :dependencies
vector (if any)?
(I am guessing something that convert :dependencies
to a hash-map and from a hash-map back to a vector maybe exists already in the boot codebase?)
Ah looks like there are no public fns, just things like (reduce #(if-let [v ( %2)] (assoc %1 %2 v) %1) {})
@nha there are a number of functions here https://github.com/boot-clj/boot/blob/master/doc/boot.pod.md#dependencies and here https://github.com/boot-clj/boot/blob/master/doc/boot.util.md#miscellaneous
@zane have you seen @danielsz's excellent "system" library? https://github.com/danielsz/system
@zane system works really well with boot, it has web server components and so on, perhaps that would at least provide inspiration for how you'd use your components in boot?
i'm just saying, you'd use your web server component in dev with system, which is something you asked about above
but you also have the option of not refreshing them, you can rebuild them immutably instead
Not by default: https://github.com/boot-clj/boot/wiki/Repl-reloading
boot is designed to be simple, which means we assume the user knows exactly what they want to do
once you start doing all kinds of things for the use you make it more complicated to understand
like if we were to add code to boot that sniffs for people using ctn and then doing things secretly to adjust their ctn configuration
However, my experience of using it so far for this project has been a maddening series of incomprehensible errors like this one: https://github.com/ptaoussanis/sente/issues/250
I would just argue that having a good story for how to interact with core libraries is probably a good idea, even if that story involves including yet another compatibility library.
sorry i hope my tone didn't come off as being dismissive, i didn't intend that but i think maybe that is how it seems?
It might be interesting for people to see an alternative to ctn that accomplishes the same kinds of productivity for you that they get from ctn.
@grant my workflow is minimal, i use vim with fireplace, and i have a separate repl server + client running at the same time in a tmux screen
my namespaces are generally organized so that reloading is easy without special tooling
So you don't use anything like Stuart Sierra's component or mount or anything like that?
> recommendations I'd probably restructure that wiki page a bit and provide a task somewhere that, when run, makes c.t.n compatible with Boot without requiring that you subscribe to automatic refresh.
the one thing i can't abide is stale state in my repl that makes me think something is working when it is only working because of some var that is in the repl that doesn't exist in my code anymore
Has anyone used pulsar (http://docs.paralleluniverse.co/pulsar/) with boot? Barring that, is there a convenient way to get the same functionality as lein :java-agents
?
I think there are some parts of boot that I still don't fully grok. It seems like using boot tasks and getting the same effects as ctn and component working together should be obvious, but it's not clicking for me at the moment.
@grant note that dependency graphs are redundant there, since boot pipelines are already linear
That, of course, means that you lose out on any benefits provided by tools that automatically manage dependencies (e.g. mount).
I get where you're coming from, but that approach probably isn't right for me, personally.
Just to check my intuition, boot runs a single pipeline per invocation. The pipeline being a sequence of tasks, that each have the cumulative fileset threaded through them. That sound right?
Knowing that there is an ordering doesn't tell you anything about what the dependencies might be.
Right. The problem I've been trying to highlight throughout this discussion is that boot is pretty hostile to people who don't "just know" things like that.
If I built a complex system where components were started and stopped in Boot tasks and introduced a new contributor to that system he/she'd have a much harder time ramping up on what the dependencies are between those components.
i think looking at a pipeline of sequential tasks is easier to grok than a web of dependencies
boot tasks are designed to be composable, which means they can't know anything about each other
like currently you can swap out boot-reload with your own live reload implementation, no problem
@dave.dixon: I haven't, sorry.
In :exclusions
, is is possible to specify a specific version? Or does it
have to go at the level of one specific dependency? Ex. (set-env! :exclusions '[[my-lib "2.0.16"]])
does not seem to work for me
So I can't exclude [org.clojure/clojure "1.2.0"]
, right? I have to put in :dependencies
for the lib. that imports it
Oh you mean not using exclusions
but put something at the top level of dependencies
? I thought they were all treated the same
the only time you'd want to use :exclusions
i think is when there are transitive dependencies that are not being used and you want to remove them from the classpath eg. to make an uberjar smaller
if you want to prevent the wrong version from being added to the classpath i would recommend just adding the right version as a dependency
also if a particular dependency is bringing in the wrong version of an artifact you could add :exclusions
to that dependency
that's nice in some ways because then you can then update other dependencies that would pull in a different version of the transitive dep
@micha You'd only use something like https://github.com/micha/multi-module-build/blob/master/build.boot when you need to run two independent pipelines at the same time. Is that correct? Basically, it just gives you a task that is equivalent to running boot in two terminals?
@grant right, plus that example has dependencies between the two, which is a little more than just running in two terminals
Pipelines are not explicit outside of something like task using comp
to put other tasks together, are they?
Has there been any thought/discussion of moving the pedestal direction? Or this works well enough so no need?
one thing that i would like to explore is decoupling the work the task does (ie. transforming the fileset) from the control flow (ie. middleware pattern etc)
but there are a ton of things that introduce coupling when you have for instance a live repl
That is what I was trying to wrap my head around. Keeping the notions of the source code, the eval'd code and the running system with all it's state clearly separated. At least as concepts in my thinking, if not artifacts in the build and running processes.
For building a jar, that seems easy to grok. Adding things like figwheel and updating the backend in a live REPL all running in the same boot process, seem to muddy the waters, at least for me at them moment.
figwheel is a monolithic thing that doesn't really integrate with boot because it assumes ownership of named files in the filesystem
you make apipeline of individual programs that do a single thing, and communicate via stdin/out
I try not to fight my tooling. If stuff feels awkward, I try to take a step back and figure out what assumptions or models are not lining up, either in my mind or between two libraries.
also a major goal is that once you have developed your own stuff you can continue to use it for a long time without updating anything
yes and exposing a low enough interface that you can add little things as you need them without disturbing your previous work
if boot does everything for you you'd end up needing to modify things rather than compose them
I like boot's trend towards simple composability over out of the box doing most things for you. We have lein
if we want something easy for the common case.
and lots of stack overflow answers for how to configure lein, so it's good for beginners in most cases
Is there a good way to think about the live REPL at the end of a pipeline? Say as somewhat similar to a target directory, just files get loaded. Or is there some other mental model I should be trying to apply when thinking about running things vs. just dropping artifacts?
the cljs-repl
task is a little different because it generates code that is compiled and sent to the client
It just exists in whatever pod it is started in. And that pod's classpath can be updated by other tasks?
other pods will have their classpaths updated also if they are created the default way, which includes the directories on the core pod's classpath in their classpaths
or if you wanted to add dependencies to the new pod in addition to the dependencies in the curent pod
But they still see whatever gets committed by another pod, as long as they are in the same place in the fielset?
(boot.pod/make-pod (update-in boot.pod/env [:dependencies] into '[[foo "1.2"] [bar "3.4"]]))
the directory in that case could contain the same contests as you'd expect in an exploded jar file
So pod's are not meant to be completely independent environments, the fileset is an orthogonal concern? They just isolate the classloaders. With multiple pipelines, you'd have independent filesets? Or not, because they both point at the same place on disk and that gets read in when it changes.
Is it wrong to think of filesets as analogous to a ring request? In the way the are what is threaded through the tasks?
you can hold onto a fileset, and later if you commit it then the underlying filesystem will correspond to that fileset object
every task runs, but they don't need to do anything unless there is something interesting in the fileset diff
instead of the build tool trying to figure out which tasks need to run based on which files changed, like in make, boot lets the task itself decide
Oh, temp files persist across runs. I had missed that somehow. I thought they were only in place while a pipeline was running.
So really the cache comes into play with something like watch, were your next task gets called multiple times.