This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-03-28
Channels
- # aws (1)
- # beginners (30)
- # boot (7)
- # cider (52)
- # clara (91)
- # cljs-dev (33)
- # cljsjs (1)
- # clojure (447)
- # clojure-brasil (3)
- # clojure-dev (16)
- # clojure-dusseldorf (5)
- # clojure-filipino (1)
- # clojure-italy (29)
- # clojure-sanfrancisco (5)
- # clojure-spec (62)
- # clojure-uk (37)
- # clojurescript (145)
- # clojurewerkz (1)
- # code-reviews (12)
- # community-development (157)
- # cursive (5)
- # datascript (1)
- # datomic (27)
- # editors (42)
- # emacs (5)
- # fulcro (31)
- # hoplon (2)
- # jobs (2)
- # keechma (1)
- # lumo (31)
- # off-topic (2)
- # om (1)
- # onyx (13)
- # parinfer (8)
- # re-frame (13)
- # reagent (32)
- # remote-jobs (4)
- # shadow-cljs (103)
- # spacemacs (15)
- # specter (10)
- # sql (1)
- # tools-deps (35)
- # unrepl (13)
right and your garden/css compiler can just use configs from garden.edn
and figwheel would run it when set to watch a css dir. Where as a cljs build tool could just use garden.edn
and ignore figwheel.edn
while doing an advanced compile. That way their configs aren't necessarily coupled together by a common project.clj
.
Ok, but that starts to seem like the same thing. Instead of a map with keys, you have a directory with files, the “path” being the key and the “file” being the value.
I just don’t get it. It seems to me that the new tool does 10% of what a build tool does and splits off a bunch of important stuff into a new configuration file. If you don’t have any complicated build rules, then this is awesome. But if you do, then you’re going to end up using a build tool anyway, like, say, lein, but now you’ve got an extra tool and an extra configuration file. In clojurescript you need something running all the time so that your repl works and so hot reloading is instant and any resource processing is watching changes. I get that it adds functionality like git integration etc., but I do not see how this really changes the way builds work.
I might have missed something, but I think it’s definitely there for simple projects and isn’t meant to be more than that.
I think it’s mainly for the use case of running something simple that also requires deps (but isn’t bundled into an uberjar).
What about this? https://github.com/robert-stuttaford/bridge
I think with the shift towards reloaded workflows using e.g., component or integrant, people are increasingly running their build processes (and auto-build watchers) from a Clojure namespace. This is what I’ve been doing for a while now (started with figwheel-sidecar). So if you’re already doing that it plays nicely with deps.edn
since you can just make dev aliases that call out to your own code to invoke builds. It does put the onus of integrating everything on the developer but I don’t think it will be too bad once some patterns emerge, build tools start supporting deps.edn, and people write new templates
Its still simple and repeatable.
@zentrope I was really referencing dnolan’s comments about build tools being “busted” from earlier today
Yea me neither, which is why I asked for more reading material from john. But I still don’t get it. I’m just trying to formulate some guidance that isn’t so abstract. So far, if asked, I’d say that tools.deps is a reimplementation of dependency management and classpath construction (with added features for git and other mechanisms) that can be called from the command line.
If all you have to do is produce a CLJS front-end (.js, .css, *.html), lein seems like overkill once you have some other way to pull in deps.
has anyone ever bumped into
ReactComponentTreeHook.purgeUnmountedComponents is not a function
when using reagent in a cljs project?i have no idea where this is coming from, and the only google foo results are talking about something like react native, which i’m not using.
It's hard for tools to evolve when they have play nicely with everything else that might play nicely with a project.clj
in the wild. A simple deps.edn
is a lower common denominator for a lot of tools. It's hard to explain how things can work just as well without a project.clj, but if the community hates the decoupling of everything, we'll probably go back to lein or some similar monolithic config file
@john If you look at that ClojureBridge registration system link above, it uses a single deps.edn (with aliases) and a Makefile as a launcher. It’s not a lot different conceptually than Lein.
And you could embed clj in a ./bin dir (and fix it so it doesn’t hard code its paths) to be self-contained.
I’m using https://github.com/juxt/mach instead of Make and loving it
make has the benefit of probably being on any given docker image you might use. But still, if i'm going to get turing complete, I want to do it in clojure 😉
One aspect David mentioned is the concept that you have minimally a -main
to run things. I developed an appreciation for that model on a project recently where I eliminated all of the crufty Bash scripts and just wrote it all in Clojure, with a -main
. With that it becomes trivial to drive such a project using clj
If curious: https://github.com/mfikes/coal-mine/commit/15078f4b390fa3166058a7e95d9a685b1f895734
On the fly, I can now point that stuff at the ClojureScript compiler sitting in a :local/root
, for example.
Interesting. I’ve been doing something similar but using multiple namespaces with simpler -main
s and keeping common config in an edn file
I guess the point is: If you decompose / decomplect, then you can re-compose in surprising ways sometimes.
So I have a web-app (server + self-hosting web-app), and instead of the main file just starting the app, it would also run “test” tasks, and an “uberjar” task and so on?
Is this the idea: instead of drafting a project.clj
and running lein
you draft a clojure build program with a -main
, presumably that uses a bunch of helpful composable libraries, and you know that will work because clj
will ensure the libraries are there based on deps.edn
?
You can have multiple entrypoints, so -main
in my-server.main
runs the server and -main
in my-server.build
handles the build logic
Don’t need lein
at all if you are fine with running something like clojure -A:build test
etc.
Perhaps another example: I was interested in producing a tool to help with automating git bisect when a ClojureScript compiler breakage occurs. I'm truly happy that https://github.com/clojure/tools.gitlibs exists as a separate thing, perhaps making such a project doable.
just in the last month or so, I've seen a ton of really cool examples of how to use clj
. I'm sure there will be quite a bit of new stuff coming up over the next year.
the build order management of make was always more suited to the vagaries of the c compiler. you don’t really need that with clojure
the ability to make simple repros has really made it a lot easier for me to contribute directly to clojurescript... I can just play with simple changes to git coordinates
Right, and to fix something in ClojureScript for a non-trivial deps.edn
based project, you just use :local/root
, pointing it at your cloned ClojureScript tree containing some speculative fix.
rich also teased something about being able to sanely do mono repos, but I haven't yet seen an example of how to do it.
how do people communicate with rich anyway. i’ve always found it intriguing. does he apparate or does he send an owl?
@zentrope It appears so. This worked in a sibling project
clj -Sdeps '{:deps {org.clojure/clojurescript {:local/root "../clojurescript"}}}' -m cljs.main -re node
I would very much like to see how a monorepo is handled
I actually do the above in a monorepo 😄
{:paths ["src"
"../honeysql/src"
"../honeysql-postgres/src"]
:deps ...
:aliases ...}
but I don't know how hacky that is 😄Yeah, with the :paths
stuff the ability to run stuff directly in Gists is a bizarre unexpected capability
I think you could use the git support with a local file://
url (which git supports cloning from natively) for monorepos
I feel this will break in unexpected ways some day 😄
This is probably my favorite cljs.main
-based gist example especially since it runs code on the classpath via @index.cljs
https://gist.github.com/mfikes/e00202b2de7cc2352fedcf92b1fe60dc
Think babel
Another example I liked: I fixed something in the compiler for someone, pushed it to my own GitHub account, and had them use my coordinates to verify the fix.
don't ever pull from a random gist if you haven't check it first. You could pull gists depending on gists, on other gists, etc 😉
clj needs a “run this crap in a docker container” flag if we’re going to run random stuff from gists
@lee.justin.m that would be cool
I have for example (defroute "/about" [] (dispatch [::events/set-active-panel {:path [:about-panel]}]))
(def routes '( ["/" [:home]] ["/servisni-udalosti/probihajici" [:servisni-udalosti :probihajici]] ["/servisni-udalosti/vyhledavani" [:servisni-udalosti :prehled]]))
(defn apply-routes [routes] (for [[path panels] routes] (defroute path [] [(dispatch [::events/set-active-panel panels])])))
not easily, you must understand that calling a macro means “rewrite this piece of code at hand during compile-time”
Is there some alternate syntax for namespaced map literals in ClojureScript than Clojure?
#:SC2APIProtocol.sc2api$RequestObservation{:observation {}}
;;valid clj
#:SC2APIProtocol.sc2api$RequestObservation{:observation {}}
;; clojure.lang.ExceptionInfo: Reader tag must be a symbol {:type :reader-exception, :line 1, :column 43, :file "NO_SOURCE_FILE"}
@kucerm2 you can easily write another macro, which given collection of routes rewrites it into a bunch of (defroute …)
forms, which then later get further expanded, because defroute is a macro
you would have to write (defroutes '([...] [...] ...))
, so that the macro gets full list of routes as a param
(def routes '(...)) and later (defroutes routes)
would not work, because your macro would see only routes
symbol
I was able to solve my problem by using the keyword function.
(defn map->nsmap
[m n]
(reduce-kv (fn [acc k v]
(let [new-kw (if (and (keyword? k)
(not (qualified-keyword? k)))
(keyword (str n) (name k))
k) ]
(assoc acc new-kw v)))
{} m))
from
cljs.user> (map->nsmap {:observation {}} 'SC2APIProtocol.sc2api$RequestObservation)
#:SC2APIProtocol.sc2api$RequestObservation{:observation {}}
pasting in the result is not valid according to the reader though. Not sure if that's intended behaviour.
@mfikes thanks for looking into it. I thought "1.9.946" would be high enough (as spec was quite a bit before it).
Yes, that version definitely has that feature. Perhaps you have a really old reader dependency?
A co-worker is asking if shadow-cljs is the right tool when looking at producing libraries consumable from JS
we only ever built spas in clojurescript so far, so this hasn't been an area of attention for us
but for a few things it would make sense if we had a way to produce JS libraries for arbitrary consumers
wouldn't lein cljsbuild
work for this?
might be work looking at how mori, a library commonly used outside of the CLJS ecosystem, does it: https://github.com/swannodette/mori
@pyr, here's the resulting JS bundle from the npm distribution: https://unpkg.com/[email protected]/mori.js
Thanks a lot @pesterhazy that will be quite helpful
PSA: :closure-defines
/ goog-define
are trivial to use. If you've never seen them before:
$ clj -m cljs.main -co '{:closure-defines {foo.core/bar 11}}' -r
ClojureScript 1.10.238
cljs.user=> (ns foo.core)
foo.core=> (goog-define bar 10)
nil
foo.core=> bar
11
They are great for "configuring" your code, and compatible with the new Shared AOT Cache feature.I’m getting the following error:
Uncaught Error: No *print-fn* fn set for evaluation environment
How do I debug this? It was working fine a minute ago. From experience the line that fixes the problem is (enable-console-print!)
. However I’ve already got this is a dev.cljs
file and my project.clj
file has the following entries:
{:app
…
:source-paths ["cljs/src" "cljs/env/dev/cljs"]
…
:compiler {:main "myproject.dev" … }
…
}
I’m quite sure I can nuke the project and start over but I want to figure out how to actually debug this. Do I throw some print statements into dev.clj
to see if it’s not being found? Is there a way to tell lein
how to spit out the classpaths?you should have a stacktrace, the stracktrace will tell you where you attempted to print
Uncaught Error: No *print-fn* fn set for evaluation environment
at Object.cljs$core$string_print [as string_print] (core.cljs:9612)
at Object.cljs$core$pr_with_opts [as pr_with_opts] (core.cljs:9776)
at Function.cljs.core.println.cljs$core$IFn$_invoke$arity$variadic (core.cljs:9819)
at cljs$core$println (core.cljs:9816)
at Function.myproject.core.fetch_webm.cljs$core$IFn$_invoke$arity$variadic (core.cljs?rel=1522263132980:18)
at myproject$core$fetch_webm (core.cljs?rel=1522263132980:13)
at myproject$core$init_BANG_ (core.cljs?rel=1522263132980:96)
at core.cljs?rel=1522263132980:98