This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-01-20
Channels
- # announcements (30)
- # babashka (118)
- # beginners (23)
- # calva (68)
- # cljdoc (10)
- # clojars (13)
- # clojure (90)
- # clojure-bangladesh (1)
- # clojure-europe (27)
- # clojure-gamedev (1)
- # clojure-nl (11)
- # clojure-uk (4)
- # clojurescript (59)
- # community-development (3)
- # cursive (13)
- # datomic (39)
- # defnpodcast (1)
- # emacs (10)
- # figwheel-main (1)
- # fulcro (18)
- # graalvm (21)
- # honeysql (1)
- # introduce-yourself (1)
- # juxt (1)
- # lsp (197)
- # malli (19)
- # off-topic (28)
- # practicalli (2)
- # re-frame (42)
- # reagent (4)
- # reitit (7)
- # releases (2)
- # sci (35)
- # shadow-cljs (13)
- # spacemacs (4)
- # vim (3)
I designed and implemented a new framework Ankbit Application Server, please have a look and any suggestions are welcome: https://www.youtube.com/watch?v=UPyEosj5zpY
The underlying platform, JavaScript, has no interfaces, so no. What's the real problem you're trying to solve?
@U2FRKM4TW porting clojure code heavily relying on interfaces to clojurescript
Then it depends on why exactly a particular interface is used at a particular place. There are workarounds but I'm pretty sure there's no one specific workaround that would let you have all the things interfaces enable at once.
essentially there is a (definterface Foo (bar [x]))
then a (deftype NFoo [^Foo y] Foo (bar [x] ...))
, and NFoo
is used in many places with calls like (.bar nfoo somevariable)
I see. Usually people use protocols for that.
But if you need an interface just to be able to use the dot form, then you can use Object
instead:
=> (deftype X [] Object (bar [_] (println "bar")))
cljs.user/X
=> (.bar (X.))
bar
nil
Hi! I have an odd issue where seemingly one core fn cannot be resolved, but others seem to work just fine. In this case all-ns
gives an error of Use of undeclared Var app.components.icon/all-ns
even though all-ns
is supposed to be a clojure core function. Has anyone ever stumbled upon this and knows what I’m missing?
You can't do runtime inspection of namespaces in ClojureScript because they get compiled away. So functions like all-ns
don't exist in cljs.core.
But I think you can get namespace data in macros using the analyzer: https://cljs.github.io/api/compiler/cljs.analyzer.api/#all-ns
I haven't done any CLJS work for a while. What's the best way to use JS libs these days ?
As far as I can tell:
• shadow-cljs is the best for npm-installed dependencies, but doesn't have any obvious way to list those dependencies in your deps.edn
or elsewhere so how do you know what npm dependencies the project depends on ?
• CLJSJS allows you to list your dependencies in deps.edn
, which I like because I like to see what all my dependencies are, but CLJSJS is out of date with most libs and requires quite a bit of work to add new dependencies (forking etc)
• :foreign-libs
is simple and you can see the dependencies, but you have to download them yourself, a minor inconvenience
For your shadow-cljs bullet point, the NPM dependencies would be in your package.json and accompanying lock file (package-lock.json or yarn.lock)
I'd prefer to keep matters as much under Clojure's control as possible though
Not sure if still applicable but I’ve seen https://github.com/RyanMcG/lein-npm in the wild
I'm using deps.edn
shadow-cljs.edn can reference a deps.edn
It makes some things harder though and is only worth if your using some other tooling in and around deps.edn, but it's not a big switch back and forth.
I always go with your first point. Managing JS dependencies should be done via JS tools. Otherwise it's a constant gamble on whether whatever mechanism you're using is recent enough to keep up with the current state of affairs in the JS world.
IMHO the only viable option is to use the npm packages directly and keeping your package.json + lockfile in version control. whether thats npm or yarn doesn't matter much. also whether you let shadow-cljs handle the JS or something like webpack doesn't matter much either, your choice there
one thing almost guaranteed to get you in trouble is ignoring package.json + lockfile and trying to "hide" them with something like lein-npm or similar stuff
In the JS world it seems, as in the Python world, you install libs without reference to a version or namespace. In the Clojure world we specify libs by namespaced library name and version. It's this dichotomy which concerns me
That's incorrect - you do specify versions, both in the JS and in the Python world, but they are optional when you install something. By default, npm
and yarn
will simply use the latest release version if you omit it during installation, but the version must be present in package.json
.
There are two differences between JS and CLJS here though:
• You have to install packages manually (there's no global analog to the .m2
folder, all node_modules
are project-specific and are populated when you run the installation command)
• Due to how version resolution works, there's an extra package-lock.json
file that's necessary. You don't alter it manually but you do put it in your repo. During development, you use regular npm i
which will change the lock file, during deployment you use npm ci
which will use the lock file to ensure same exact versions are being used
just to expand why you must keep the lock file. in npm it is very very common to use version ranges when declaring dependencies, most libraries do this. so even if you specify to depend on lib-a with exactly version 2.0.0, that lib may depend on lib-b version ^4.0.0. which basically means 4.0.0 or anything newer. so without a lockfile if you run install again you'll never know what you get. the lockfile ensures you always get the same.
otherwise it is not uncommon to end up with lib-b version 4.5.0 that broke lib-a in some way and now you entire thing is broken. lockfiles save you at least that headache.
@U2FRKM4TW yes but think of the difference between what you do when you want to use a Clojure lib vs a Python/JS lib when you read the github page: for Clojure you will see a namespaced library name and version number x.y.z/lib-name {:mvn/version "a.b.c"}
to paste into your deps.edn
whereas for Python/JS you will see npm install lib-name
or pip install lib-name
It's not a namespace, it's a group. It's just a way to make names more unique, that's all. JS is slowly moving in that direction as well. And yes, you don't have to specify versions when installing a JS/Python lib. But you can if you want to.
uhh in Maven terms it's a group, in Clojure terms that symbol's namespace!
(namespace 'org.clojure/clojure)
=> "org.clojure"
anyway zoom out - I'm talking about the difference in development process here
For symbols - yes. :) But we're in the context of dependencies.
Library org.clojure/clojure
is a library with name clojure
that belongs to a group named org.clojure
.
Symbol org.clojure/clojure
has name clojure
and namespace org.clojure
.
The fact that at least deps.edn
and project.clj
represent library names as symbols is not central here.
yes yes I know
can we talk about the actual point of the thread
ok no need to reply then
maybe it would help if I put it this way: if you had the choice between the Clojure way of managing dependencies (`deps.edn`) and the JS way, which would you choose for JS dependencies in CLJS projects ? If you could use the Clojure method would you ?
Before answering that question, I would have to read up quite a bit on how exactly NPM does its thing, decide on what the implications of any potential changes to those algorithms are, study the implementation of the CLJ solution for JS dependencies, and assess how much of a risk using it would be. Given that I don't really want to do all that and that using NPM is perfectly fine the vast majority of the time, realistically I would probably wait for a good few years and study other people's experiences and analyses before adopting such a solution.
And if that CLJ mechanism for JS dependencies is CLJSJS then the answer is a definite "no". I used to use it ~4 years ago or so, and I'm glad I've stopped.
@U0CKDHF4L that is a pointless question. we gotta use what is available, not what we wish was available. we provided a lot of information, you can make your own choice. FWIW compare the "dependencies"
of package.json
and :deps
in deps.edn
and they'll look very similar. no difference if you ask me.
I think that question has merit - if I were willing to put time and effort into improving the situation by creating new tools, I would've probably asked the same question. After all, you yourself created a new tool at some point - you didn't settle on what was available. :)
but note that the problem here really isn't in the tool. it is the entire ecosystem. if nobody was using version ranges you'd have a similar setup as in maven.
also npm has different conflict resolution strategy. that would also need to change. really you have to replace all of npm to make any meaningful change 😛
Hi, I have kind of an odd issue. I’m currently using a component library that has a dialog trigger which is a button
under the hood. You can pass a prop called as-child:true
which will merge all props into the child component. However, if you have another component as the child, it doesn’t seem to work.
This works fine in React, so I’m wondering if I’m missing something.
Here’s a simple example, and https://www.radix-ui.com/docs/primitives/components/dialog
(defn dialog [children]
[:> Dialog
[:> DialogTrigger {:as-child true :aria-label "Placeholder"}
children]])
(defn share-dialog []
[dialog
[button {:class "bg-black text-white"} "Open"]])
try calling reagent.core/as-element
on children
before it's passed to the DialogTrigger
no luck
So, since a HTML <button> works with it. It’s probably that I need a way to pass props into <Button> with something like a forwardRef
What is compiling that code into react? It might need to to pass a js object not a clojure hashmap. Are there errors?
this is what we’ve had to do lol.. it’s still not perfect as it fails with other radix components, but very close
hoping there’s an easier way at this point
Hi all, using the latest clojurescript, set up according to the quick start, I'm getting warnings when using goog.labs.userAgent.browser
. Any idea why this is happening?
(require '[goog.labs.userAgent.browser :as gbrowser])
;; => nil
(gbrowser/isChrome)
;; WARNING: Use of undeclared Var goog.labs.userAgent.browser/isChrome at line 1 <cljs repl>
;; => true
It's interesting that I get the warning, but then the function works just fine. Note that in a project more complicated than a quick start this is causing builds to fail.^ nvm, already reported at https://clojure.atlassian.net/browse/CLJS-3344