This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2019-11-15
Channels
- # announcements (1)
- # aws (79)
- # babashka (47)
- # beginners (82)
- # calva (65)
- # cider (27)
- # cljdoc (18)
- # cljs-dev (29)
- # clojure (189)
- # clojure-dev (5)
- # clojure-europe (3)
- # clojure-italy (1)
- # clojure-madison (6)
- # clojure-nl (4)
- # clojure-spec (10)
- # clojure-uk (41)
- # clojured (3)
- # clojurescript (5)
- # clojurex (17)
- # cursive (30)
- # data-science (7)
- # datomic (17)
- # emacs (3)
- # events (6)
- # fulcro (2)
- # funcool (9)
- # graalvm (29)
- # jobs-discuss (3)
- # joker (3)
- # kaocha (6)
- # malli (5)
- # music (6)
- # off-topic (21)
- # reagent (3)
- # reitit (4)
- # rewrite-clj (8)
- # shadow-cljs (49)
- # spacemacs (7)
- # sql (23)
- # tools-deps (15)
- # vim (43)
- # xtdb (19)
Hi 🙂 I'm want to build an app that has a non-Clojure backend and a ClojureScript frontend. It is my (possibly wrong or naive) understanding that there are two ways of handling deps, packaging, and minification etc. in the frontend – webpack and Leiningen. I can find plenty of information about how to set up both, but it is not clear to me what exactly the trade-offs of either choice are. Leiningen appears to be the default choice, but are there any advantages of using webpack in an app that hopefully won't have to use plain JavaScript (presumably, in that case webpack would be the way to go?)? Thanks.
if you aren't using maven for dependencies, leiningen might not be the right tool for deps - it's primarily(?) a dep resolution tool
I can't speak to what the best choice is for js, but it would make sense to use a js dep manager for an app with no jvm clojure code beyond the cljs compiler itself
I hear shadow-cljs is good
Ah I suspect my understanding of how the different parts fit together is incomplete and incorrect then. I'll have a look at the tools you mentioned, thank you 🙂
it's slightly weird because clojure and clojurescript are each java libraries you would fetch from maven, and lein is the most popular way to manage projects that use clojure
it actually launches java with your deps and the entrypoint you ask for
(or the implicit one eg. for a repl)
Hm...upon reading up on it some more, I'm starting to wonder if it makes any sense at all to use ClojureScript in the frontend without a Clojure backend.
I believe there are benefits: dead code elimination, less tooling, language consistency, immutable state, spec, a stable environment, google closure library…the benefits are significant. I will eventually write a review of the above, but until then you can get a feel for it with https://betweentwoparens.com/start-a-clojurescript-app-from-scratch
it's definitely done, but you end up pulling in java + clojure just to run the clojurescript compiler in most cases
in your build that is
@conceivably I use CLJS as front end with python Backend, and it has been a joy to develop.
@neo2551 Is there any boilerplate that you know for CLJS, similar to create-react-app?
https://www.reddit.com/r/Clojure/comments/7885ox/tutorial_clojurescript_with_leiningen/
I would start with shadow-CLJS and the re-frame todomvc
There is also a create CLJS project I don’t really remember
But shadow-CLJS helps a lot
The hard part is the tooling.
If you don't want to setup your own tooling https://github.com/filipesilva/create-cljs-app/
@UQJN0CEN8 https://betweentwoparens.com/start-a-clojurescript-app-from-scratch and https://github.com/tkjone/create-reagent-app (which is the automated version of the blog post)
Hi. I am struggling to get a repl up and running with Leiningen on Windows Server 2019. I keep getting Caused by: java.net.ConnectException: Connection timed out: connect
, I've tried a couple of different ports, but no luck. Any ideas? lein ring server
is able to get a server up and running without a hitch.
@byrongibby Perhaps it's a firewall issue blocking the connection on the nREPL port?
@seancorfield Hey. In that case wouldn't it make it impossible to start a server serving off the same port?
lein ring server
just starts a server process. lein repl
starts an nREPL server and client and tries to connect the client (the interactive REPL) to the server (nREPL). I've definitely seen that fail on Windows.
Okay, let me do some further research.
You may need to specify the host as 127.0.0.1
for lein repl
-- I think it may try to bind to 0.0.0.0
by default? Or maybe it's the other way around.
I tried both.
It may also differ for IPv6 / IPv4 (but it's been years since I worked with lein
).
(and never much on Windows)
You use boot?
I will ask IT for assistance, the network guys should be able to help me out if I can adequately describe the problem. Thanks for the help as always.
Switched completely to Clojure's CLI/`deps.edn` last year (from Boot -- we'd switched from Leiningen to Boot back in 2015/2016)
Also ask in #leiningen -- it's likely a common, known issue on Windows systems (and probably Windows Server specifically).
Welcome @tony050!
@seancorfield 👋:skin-tone-2:
i'm trying to do a simple javascript ajax POST but i keep getting 403 forbidden
<script type="text/javascript">
function sendMark( kanji, meaning)
{
console.log ( kanji, meaning, '{{aft}}');
var sendMarkData = { 'kanji': kanji,
'meaning': meaning,
"__anti-forgery-token": '{{aft}}' };
var xmlHttp = new XMLHttpRequest();
xmlHttp.onreadystatechange = function()
{
if(xmlHttp.readyState == 4 && xmlHttp.status == 200)
{
alert(xmlHttp.responseText);
}
}
xmlHttp.open("POST", "/mark-mk");
xmlHttp.send(sendMarkData);
}
</script>
CORS perhaps @sova?
Yeah that's my suspicion, I thought adding the anti-forgery-token into sendMarkData would handle tha
That's for CSRF tho', CORS is about how your backend handles OPTIONS
requests for preflight checks on other actions.
I am vaguely aware of preflight checks
what does CORS need that I'm not doing? looks like xmlRequest.open and stuff?
The browser sends the preflight check automatically. It's purely a backend thing.
So your backend needs to support /OPTIONS
and respond appropriately. If you're using Ring, add ring-cors
as your outermost middleware.
(CORS violations give pretty sizable warnings in your browsers console)
I am not getting very much in terms of feedback in the browser so.. yeah I will add ring-cors 😄
so if I'm adding middleware to something like this...
(defn -main [ & args]
(server/run-server (wrap-defaults all-routes site-defaults) {:port 8117})
(println "server on @ localhost:8117"))
Well I wrapped it but I still get a 403 in javascript console
fobidden
Ah thanks so much y'all! @seancorfield @lennart.buit
Sorted it out finally ^.^
+CORS + xmlHttp.setRequestHeader('X-CSRF-Token', '{{aft}}')
So... I have a vector of maps
I'd like to remove the first occurrence of a match on all keys and values...
actually it could just match on one k-v, but i'm not sure how to do "remove one" from a vec
There's probably a smarter way to lay this problem out
If there are multiple matches, you only want to remove the first one and leave the rest in there?
it's kinda like I have values that can be A, B, C, D, and they get counted... like 4 As, 4 Ds, 1 B, 1 C, and when I click remove A it should get rid of just one. I suppose keeping a count makes more sense.
I have been conj'ing [{m1} {m2} {m3}] and i'd like to remove one of the {m}s if on an identical match, but just one
i naively tried something like (swap! jpc-users-atom update-in [email :kanji-stumbles] disj {:kanji kanji :meaning meaning})))
come on man let me build my tooth pick skyscraper lol
Tooth picks:
user=> (def v [{:a 1 :b 2} {:a 1 :b 3} {:a 2 :b 1} {:a 2 :b 2} {:a 3 :b 3}])
#'user/v
user=> (let [seen (atom false)] (reduce (fn [v m] (if (and (= 1 (:a m)) (not @seen)) (do (reset! seen true) v) (conj v m))) [] v))
[{:a 1, :b 3} {:a 2, :b 1} {:a 2, :b 2} {:a 3, :b 3}]
user=> (let [seen (atom false)] (reduce (fn [v m] (if (and (= 2 (:a m)) (not @seen)) (do (reset! seen true) v) (conj v m))) [] v))
[{:a 1, :b 2} {:a 1, :b 3} {:a 2, :b 2} {:a 3, :b 3}]
user=> (let [seen (atom false)] (reduce (fn [v m] (if (and (= 3 (:a m)) (not @seen)) (do (reset! seen true) v) (conj v m))) [] v))
[{:a 1, :b 2} {:a 1, :b 3} {:a 2, :b 1} {:a 2, :b 2}]
user=>
🙂 🙂you basically what the same data available sorted 2 different ways, insertion order and then a composite of your A B C D tags and insertion order
the insertion order sort mimics the vector, and the sort on tag and insertion order lets you lookup the "first" inserted of each tag
your point is indisputabo @hiredman ... however i realize that i am making it complex for no reason, i can just store :keyword instead of a map for each entry. i'm not sureally how (not @seen)
works up there @seancorfield is it a bitwise comparison of T/F of sorts?
@sova Logical negation. seen
contains true
or false
. (not @seen)
is therefore false
or true
respectively.
usually if you are using a mutable store as a one-way switch you can use delay
or promise
and check the realized?
status
user=> (let [seen (delay true)] (reduce (fn [v m] (if (and (= 3 (:a m)) (not (realized? seen))) (do @seen v) (conj v m))) [] v))
[{:a 1, :b 2} {:a 1, :b 3} {:a 2, :b 1} {:a 2, :b 2}]
it looks nicer if you also have (def open? (complement realized?))
or whatever name you like for the opposite check