Fork me on GitHub
#clojurescript
<
2020-06-01
>
didibus03:06:48

I'm a bit confused about having a ClojureScript lib depend on another

didibus03:06:48

I've got one ClojureScript lib which itself depends on some node_modules. It uses npm-deps and install-deps. I can do an advance compilation of it just fine it seems, even though I don't define any libs or foreign-libs (which also surprises me). Now if I have another lib depend on that one using deps.edn local deps, when I try to advance compile that one, it complains that the namespaces in the lib can't find their dependent JS from node

didibus03:06:09

So it makes a bit of sense to me, since deps.edn won't be pulling in transitive node deps. But what am I supposed to do here?

didibus03:06:43

Is there a way to do a "uberjar" style bundle of the lib, so it would contain within itself all the node deps?

didibus03:06:06

Should I tell users they need to add the npm-deps to their own build when using my lib?

coby04:06:56

Honestly I would just use shadow-cljs

didibus04:06:49

Hum.. maybe I should. But I'm trying to understand.

coby04:06:18

I banged my head against the wall for a long time trying to get CLJSJS/deps.edn to work with NPM, whereas shadow worked the first time I tried. I still don't really understand CLJSJS, for better or for worse 馃槄

didibus04:06:23

Also, with shadow-cljs, would I be able to have one ClojureScript lib depend on another when the other one depends on npm deps ?

coby04:06:31

I'm not sure...that might depend on the mechanism through which your CLJS dependency brings in the NPM dep. If it's via shadow-cljs I believe it should "just work" because shadow pulls in what it needs and does module-level tree-shaking. If it's through CLJSJS, it might be more complicated. It's worth asking in #shadow-cljs. A big reason I prefer shadow is that Thomas Heller (the main author) hangs out in that room and is somehow able to answer pretty much all the questions people throw at him.

didibus04:06:41

Ya I can see that. It seems there's way less ClojureScript experts than there are Clojure, hard to get your questions answered

coby04:06:23

I can relate to that. Moving to shadow-cljs was a pretty big shift for me in that regard

didibus04:06:27

I guess one nice thing about shadow-cljs is that it'll do tree-shaking and minification of JS deps. And also perform advanced compilation on your ClojureScript code.

didibus04:06:05

It seems with the cljs compiler, you can't do that. You can't even have the JS deps go through simple optimization while your code goes through advanced

coby04:06:36

Yeah, that is the nicest thing about it IMO

didibus04:06:15

You can use the new bundle target I think kinda. But then it's like a two step process. You need to compile your code with bundle, and then you need to learn to use some JS bundler on top

coby04:06:35

Tied, I guess, with the NPM integration

coby04:06:01

I barely have to think about bundling since switching to shadow-cljs...the most involved I've had to get is code splitting w/ modules, but there's a pretty good story for that too

didibus05:06:18

Ya, I might have to drop in the towel and switch to it :p Even if I get it working, doing two bundle, first bundling my code with target bundle and then rebundling it with webpack feels pretty annoying. And still, I'd be confused about how to manage the dependencies.

coby05:06:10

I feel ya. Webpack is a four-letter word to me

didibus05:06:46

I'm still curious though. So if I use shadow-cljs, and I have lib A depend on NPM packageX version 1.2 and now say I have lib B depend on NPM packageX version 2.0 and now I have my app depend on both lib A and lib B? What happens? Assuming lib A and B are both ClojureScript libs?

sergey.shvets20:06:51

Npm has a way of handling this. Don't remember what's the name, but it somehow local scopes it. I assume that 2.0 has some breaking stuff and just putting 1.2 in exclusions isn't enough? I would second coby and say that overall shadow-cljs is the way to go. If you already getting that deep into javascript land the less intermediate layers you have the better. I used to hack with cljsjs/cljs-oops and externs and I eventually gave up (and I think I turned away from CLJS a few peeps at a local meetup after showing them the hoops they have to jump through). Shadow so far was a breeze and I'm able to use plenty of npm libraries with no problems.

coby05:06:56

Well, so in normal JS land, npm would complain about a conflict like that right? I don't recall but I think that's how it works. Anyway I'm pretty sure shadow-cljs just defers to npm on that. Another great question for #shadow-cljs though

didibus05:06:46

Well, maybe in pure npm world. But here I'm also depending on ClojureScript libs. So I'm curious how that would mix.

coby05:06:19

yeah I'm just making an educated guess

didibus05:06:58

Cause that's my understanding of cljsjs. Its that, effectively, you can't just do an uberbuild of your cljs lib if it depends on external JS. Because then the JS deps versions Are untracked. Instead, you need to bundle each JS dep as a ClojureScript lib with a version. And each of their deps also has to be bundled. Etc.

didibus05:06:34

That way, tools.deps or lein can now fully resolve everything and all conflict.

coby05:06:12

yeesh. Yeah I never even got that far with cljsjs. Good luck!

didibus05:06:50

What I understand till now is you can list npm-deps, and cljs compiler will pull them down (if you have install-deps flag). Now to bundle them, you can specify them as either a :libs (which only work if they use google style modules). In that case, they get fully advanced compiled and all. Or you can specify them as a foreign-lib (which you need to do if they are not using google modules). As a foreign-lib, they get bundled in untouched.

didibus05:06:49

But this works for direct dependencies. Once you get to transitive, like my use case, having a ClojureScript lib that depends on a JS lib. It seems you're kind of screwed. Either you have to basically repackage every NPM libs as a Clojure lib (which is what cljsjs tries to do). Or I guess you just bundle them and hope you don't face conflicts. Or you don't bundle them and have to tell users they need to pull them down themselves.

admarrs10:06:08

I tried to create a simple executable following the process outlined here https://clojurescript.org/guides/native-executables but simply get Invalid Nexe binary

admarrs10:06:31

This was using wget rather than the older version in the guide.

admarrs10:06:42

Anyone else had similar issues?

Morong脰a10:06:17

what is the best form validation library that works in Clojure and ClojureScript, can I use clojure spec?

kwladyka11:06:15

Maybe this will be helpful, this is only for cljs but explain how to do this https://clojure.wladyka.eu/posts/form-validation/ and https://github.com/kwladyka/form-validator-cljs . You can use cljc spec defines in Clojure and ClojureScript and this should work as you expect.

Morong脰a14:06:37

I saw this, but my I am using react and hooks are first class in react. I do not like they are using atom

Morong脰a14:06:02

If I can make it work with hooks

Shako Farhad15:06:32

Hey mate. I don't think you need anything special for form validation. This is how I have solved it:

(defn input-regex [input-type]
  (case input-type
    :name
    #"^[a-zA-Z]{1,40}$"

    :email
    #"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,63}$"

    :number
    #"^[0-9.-]{1,40}$"

    #"^[a-zA-Z0-9.-]{1,40}$"))

(defn validate-text-input [input input-type]
  (if (and (not (nil? input)) (string? input))
    (string? (first (re-seq (input-regex input-type) input)))))
It is all just regex based. All I do is call my function like this: (validate-text-input "Hello" :name) (validate-text-input "2424" :number) (validate-text-input "<mailto:[email protected]|[email protected]>" :email) You can of course add more regular expressions and customize those as you like. The validate function above just returns true or false. Which I find very handy in my input fields.

Morong脰a13:06:08

I ended up using clojur spec with phrase. To phrase my validation errors. That way I have a consistent way to validate both the backend and frontend.

Karol W贸jcik20:06:10

How can I indent a output by two spaces using clojure.pprint?

noisesmith20:06:55

I think the easiest way would be combining with-out-str and a string replace

Karol W贸jcik20:06:10

Yep. This is what I planned to do, but I found http://clojure.github.io/clojure/branch-master/clojure.pprint-api.html#clojure.pprint/pprint-indent & it's seems like it can help here, but dunno how to use it.

noisesmith20:06:29

fascinating - I guess you'd need to ensure your data is wrapped in a "custom dispatch function" referenced in the doc, I don't know what that is off the top of my head though

noisesmith20:06:40

maybe the namespace for clojure.pprint would be more revealing?