Fork me on GitHub
#clojurescript
<
2019-04-29
>
emilaasa07:04:00

Is there a recommended way to get started with a good cljs stack?

Piotr Roterski09:04:00

I’m in similar situation as you, coming from js spa world. My personal bet is on fulcro (http://fulcro.fulcrologic.com/). It’s a fullstack framework that js have been missing since meteor.js but without its compromises and locking you to mongodb. Fulcro solves all the mess with state-management/data normalisation that redux/graphql try to deal with but without much of its boilerplate complexity because it’s fullstack in clojure. I’m only starting with it so I don’t know how it works in practice and you could probably hack something similar using reframe, but fulcro seems more like a battery-included complete solution.

helios10:04:04

I recommend taking a look at http://www.luminusweb.net/ which is nothing more that a collection of libraries commonly used in clj(s) world. otherwise, why not just taking a look at reagent and their template? https://github.com/reagent-project/reagent

👍 4
helios10:04:38

Otherwise, since you have experience with redux, take a look at re-frame 😄 https://github.com/Day8/re-frame

emilaasa12:04:30

Interesting thanks for the suggestions!

orestis13:04:53

Use shadow-cljs as your build tool to get many batteries included too.

emilaasa07:04:18

Or getting started with cljs maybe

emilaasa07:04:23

My familiarity level is about as follows: - familiar with FP concepts - a few years javascript / SPA experience using hacked together FP (i.e redux like stuff and various stream libs) - few years JVM experience, mainly Java and Kotlin - done some very basic Clojure Koans and such

emilaasa07:04:18

I’ve watched a figwheel demo and it looks very convincing, and vdom diffing + persistent immutable datastructures seems very solid for SPAs

Frank Henard19:04:26

You will have to get to know the different build tools and make a decision there. Leiningen is good, and works with figwheel. That's what I use. There's also something called shadow-cljs which seems to be getting some attention lately

Frank Henard19:04:00

I'm somewhat of a beginner in CLJS myself, though I'm probably intermediate at Clojure

Frank Henard19:04:54

the CLJS quickstart linked above, I believe, is the most barebones. The goal with that is to help you understand what's really going on without the getting overwhelmed with the build tool

Frank Henard19:04:25

Unfortunately, it probably seems like there's too many tools options at the moment. Clojure(script)'s standard tooling has changed recently, so the surrounding community tooling is also changing

Frank Henard19:04:58

I just noticed the previous thread. Sorry about that

emilaasa20:04:44

Thanks for the replies!

Olical09:04:53

Mornin'! Anyone know which bindings I might be able to set to tell CLJS which file and line offset the code should be evaluated at? So that (def... meta data is set accordingly. There's things like *file* in Clojure but I wasn't sure if CLJS had an equivalent.

Olical10:04:21

Clojure lets me do some fun things (https://github.com/Olical/conjure/blob/c6963558db9de92573c4cf13fa50d06be2acd42e/src/conjure/code.clj#L57-L61) but I won't have access to eval in ClojureScript, so it needs to be configured in the current eval environment. Maybe that's impossible, even if I can only set the path to the current file is better than nothing 😄

Olical10:04:47

I have a feeling cljs.analyzer/*cljs-file* might be the only hook open to me but I'm not sure.

dominicm10:04:38

The piggieback source might be useful

thheller10:04:40

@U38J3881W do you eval a string or a clojure form?

Olical10:04:14

This is a string being sent through a prepl, but we can think of it as any normal REPL eval.

Olical10:04:30

So imagine trying to set the current file in a REPL eval, that's kinda the context I'm working with.

thheller10:04:49

so this isn't self-hosted?

thheller10:04:14

which exact API do you use then?

Olical10:04:15

It's regular old REPL ClojureScript.

thheller10:04:46

no such thing 🙂 there are many different impls

thheller10:04:20

cljs.repl.node?

Olical10:04:04

Ah, yes, in my current context it would be the node repl, sorry.

Olical10:04:19

I think the best I will get is binding the current file path.

thheller10:04:51

so you do not control the other end of the prepl? you just assume its a CLJS prepl?

Olical10:04:20

Yup! Hence the lack of self hosting etc. I'm looking for a pretty generic binding which may not exist.

thheller10:04:45

well it is determined at read time

thheller10:04:55

so if you control the reader you can do pretty much anything

Olical10:04:42

Oh interesting.

thheller10:04:12

take a look at that fn impl. SourceLoggingPushbackReader. contructor accepts a line and column arg

thheller10:04:33

although not exposed by default you do "cheat" and override it after construction 😛

thheller10:04:46

or just construct manually

thheller10:04:00

but this assumes you control the reader

thheller10:04:24

the reader will attach the proper metadata to the read CLJS forms and that is that the analyzer/compiler uses

Olical10:04:28

Haha, okay, interesting. I'm already using LineNumberingPushbackReader for the Clojure approach. My constraint is that I don't control the prepl / server side so it might not be possible but I'll have a play.

Olical10:04:52

And the file / line changes potentially on each eval.

Olical10:04:00

Since I'm sending forms from my editor.

thheller10:04:34

yeah the default REPL impls have no way to control that

Olical10:04:43

sad trombone

thheller10:04:23

you could just go with the metadata route though. it might work

thheller10:04:59

instead of sending "(def x ...)" over the wire you send "^{:line 123 :column 456} (def x ...)"

thheller10:04:12

I'm not sure if that will work for CLJS though

Olical10:04:12

Yeah, did consider that sort of thing but would like to avoid it if I can. A binding or something would be ideal, if I can't do it I can't do it. Not a massive deal. I'm trying to touch the contents of the eval and the remote end as little as possible to ensure compatibility with all envs and future setups.

Olical10:04:57

Besides, it'll probably be mainly compiled by figwheel / shadow-cljs anyway, it's Clojure where I needed the line/file data really.

awb9913:04:20

Is there any 2d drawing library that works nicely with reagent? I tried using quill, but I cannot get it to draw anything. Any ideas?

Eric Ervin19:04:31

there is a #quil channel if you ever need it

awb9913:04:35

very cool! Thanks @U08E8UGF7

awb9913:04:12

But will p5.js also work with reagent?

kszabo13:04:31

it seems to work with react

kszabo13:04:42

so I don’t see a point why not

awb9914:04:33

thanks. sounds very difficult to implement. a lot of js wrappers needed 😞

kszabo14:04:09

I would try anyway, I usually found out I need way less wrappers if I do it myself in cljs 🙂

kszabo14:04:21

especially if you are already using shadow-cljs

awb9914:04:32

I am really bad with js interop.

awb9914:04:40

I was hoping to find something that works more out of the box.

awb9914:04:10

And reagent would lend itself perfectly to this because of the state management and perhaps a few "normal html" components to add some controls.

zane16:04:02

Has anyone had luck getting Handsontable to work with advanced compilation via externs? It's on CLJSJS, but the version there is very old.

tyler16:04:25

What does the error message Can't take value of a macro cljs.core/or mean?

Jimmy Miller18:04:16

or is a macro. It expands into other code. So if you try to do something like this:

(reduce or [false false false true])
You will get that error. This code is trying to treat or as a function, but it isn't. You can fix this by wrapping it in a function.
(reduce (fn [x y] (or x y)) [false false false true])

dnolen16:04:35

you're trying to pass it as a value

dnolen16:04:47

(partial or ...) or something like that

dominicm16:04:50

Sometimes Figwheel can accidentally trigger it too

dpsutton16:04:01

was the patch ever applied?

dominicm17:04:51

Patch is merged but not released

dominicm17:04:03

May be available in the 2.0.1 snapshots

tyler16:04:30

I’m seeing it in figwheel so that’s probably the case. The warning is coming from the line (if (or disabled? all-invoiced?) ...) where disabled? and all-invoiced? are booleans, I would think that would be OK.

dpsutton16:04:14

are you on cljs 1.10.520?

dpsutton16:04:34

try the 443 439 i think? it should go away. and if so its figwheel's fault

tyler19:04:47

This worked, thank you

jeaye17:04:40

CLJS (`1.10.439`) should shim process.env.NODE_ENV, right? I'm setting :closure-defines {process.env/NODE_ENV "development"} and I see "process.env\/NODE_ENV":"development" in CLOSURE_UNCOMPILED_DEFINES in my generated output. Alas, I'm still seeing React throw up process is not defined when it checks for process.env.NODE_ENV. What am I missing?

orestis01:04:07

You might need to pass in the munged name as a string, instead of the CLJS name.

hoopes19:04:00

Hi, I was hoping someone could help me with using react-dropzone from cljs. My (hyper-simple) code is here: https://github.com/hoopes/dropzone-poc/blob/master/src/main/demo/core.cljs - I'm using shadow-cljs, and the error I'm getting is

Uncaught TypeError: Cannot convert a Symbol value to a string
    at Array.join (<anonymous>)
    at Function.cljs$core$IFn$_invoke$arity$1 (cljs.core.js:10144)
    at Object.cljs$core$pr_writer_impl [as pr_writer_impl] (cljs.core.js:33441)
    at cljs$core$pr_writer (cljs.core.js:33472)
    at cljs.core.js:33992
    at Object.cljs$core$pr_sequential_writer [as pr_sequential_writer] (cljs.core.js:33163)
    at Object.cljs$core$print_prefix_map [as print_prefix_map] (cljs.core.js:33981)
    at cljs$core$print_map (cljs.core.js:34002)
    at Object.cljs$core$pr_writer_impl [as pr_writer_impl] (cljs.core.js:33371)
    at cljs$core$pr_writer (cljs.core.js:33472)

hoopes19:04:50

is that a common error? google doesn't seem to know much about it, unless my google fu is just broken

hoopes19:04:54

in the str function in core.cljs, x appears to be a Symbol(react.forward_ref)

dnolen19:04:36

Symbol has no toString method, you cannot print it

hoopes19:04:18

would that imply the bug is in the react-dropzone lib then?

hoopes19:04:39

sorry, this is kinda down further in the weeds than i'm used to

LorenzoEvans19:04:54

Would anyone know how to deal with a

Java.lang.ClassNotFoundException: javax.xml.bind.DatatypeConverter
clojure.lang.Compiler$CompilerException: java.lang.ClassNotFoundException: javax.xml.bind.DatatypeConverter, compiling:(org/httpkit/server.clj:1:1)
error? I'm working on the modern-cljs tutorial, and got a bare-bones web app to run, but whenever I try and run (start-repl) to run the boot-cljs-repl, I get that error. I've tried updating Clojure, ClojureScript, Adzerk and other related dependencies to their newest versions, and have tried $ echo $BOOT_JVM_OPTIONS to add it to the boot.properties file (which I can open or cd into), to add it, along with "--add-modules" "java.xml.bind" from the CLI. I would add it in the project.clj(s) file, but there isn't one mentioned in the tutorial yet, and I don't want to add it and mess things up more.

wiseman21:04:22

cljs-http seems to be mangling binary data in the response (e.g. if i’m requesting a jpg). anyone know how i can avoid that, or is there a nice alternative library I can use? (i’m using node via shadow-cljs)

martinklepsch21:04:30

@wiseman there's goog.net.Xhrio that might be easy enough to use depending on what you're doing specifically

martinklepsch21:04:46

most of the cljs http libraries wrap that in some capacity

wiseman21:04:33

i’m doing totally basic http. cljs-http just came up at the top of a google search, but i can probably do whatever the popular approach is.

dntn22:04:10

@hoopes did you ever figure that react-dropzone thing out? I have a cljs project that I was able to use react-dropzone in with your sample code, but cloning and running your repo I get your error :thinking_face: ;

thheller22:04:35

@hoopes the issue it that you only depend on re-frame but not reagent. re-frame still seems to depend on [reagent "0.7.0"] which seems to have issues with the newer react stuff

thheller22:04:14

adding [reagent "0.8.1"] seems to fix that problem, still fails elswhere though

thheller22:04:48

funny enough it tries to tell you that but can't due to the unprintable Symbol instance 😛

dntn22:04:04

Ah so that's why it still fails in react-dom with ...got: object after adding the [reagent "0.8.1"]; I couldn't find any difference between my and @hoopes’s shadow-cljs.edn and package-lock.json that was the magic bullet (I had also noticed the lack of reagent dependency and tried to match other dependency versions) so I'd be interested to learn what fixes that issue even though I am not facing it :thinking_face:. Good luck, @hoopes 😬