This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
- # ai (1)
- # aleph (11)
- # announcements (9)
- # aws (1)
- # beginners (61)
- # chlorine-clover (2)
- # clj-kondo (1)
- # clojure (35)
- # clojure-australia (1)
- # clojure-china (1)
- # clojure-europe (1)
- # clojure-filipino (1)
- # clojure-france (2)
- # clojure-hk (1)
- # clojure-indonesia (1)
- # clojure-japan (1)
- # clojure-korea (1)
- # clojure-my (1)
- # clojure-sg (1)
- # clojure-taiwan (1)
- # clojure-uk (1)
- # clojured (14)
- # clojurescript (45)
- # cursive (8)
- # data-science (2)
- # events (1)
- # fulcro (2)
- # gratitude (4)
- # helix (1)
- # honeysql (3)
- # introduce-yourself (1)
- # malli (4)
- # minecraft (4)
- # nbb (23)
- # off-topic (57)
- # polylith (4)
- # reagent (2)
- # sci (23)
- # shadow-cljs (7)
- # vim (1)
- # xtdb (17)
I don’t believe that they’re actively maintained, and I would not recommend them! They are still in use in codebases, but probably mainly as legacy code -I can speak from experience here 🙅
I am looking into RUM these days since I heard people recommending it from time to time. One reason is due to the server side rendering. But other than it, how does it compare to reagent and what pain points does it solve compared to reagent?
Also, for server side rendering, does it assume we have to use nodejs as the backend? Or else how does we invoke react to generate html on the server side?
It renders hiccup to html on the server-side, once it is loaded on the client, the html is enhanced to connect to a react component
So it only does SSR for the first page load, if the user than interacts with JS components that will use react on the client side
> It renders hiccup to html on the server-side Is react relevant to this? Sounds like SSR is all about Clojure (hiccup) stuff. My initial impression was, SSR sounds like running react on the server side to pre-generate the html needed.
Well, react is relevant in that the rendered HTML from Rum can connect to a react component on the client side. So it's still an interactive page, just the first render is done on the server
If you don't need interactivity (beyond what HTML can do), you can just use Hiccup directly, no need for anything else, and you don't even need JS and thus Clojurescript
Technically Rum can be used instead of Hiccup, it has its own renderer for Hiccup that's supposedly claimed to be faster. So it can be used without React for just standard HTML SSR without interactivity, but a lot of the features won't be useful, it's just a way to organize hiccup basically.
Generally people want to create a highly interactive web page powered by React, and also have SSR so the first page load is faster and search engine can index the content. That's where Rum shines as it can render the first page and then let React take over for interactivity.
SSR with rehydration is a React thing. SSR with Rum is interesting because it doesn't force you to use JS on the server like doing it directly in React would, i.e. if you're rehydrating React components then you're probably using JS on the sever too, but with Rum you can just use JVM Clojure and get the regular Clojure backend experience.
mathbox-react, an npm package with 54 existing React components.
I’d like to emit a line like this for each component:
I know that the user can already call
(def ComponentName (r/adapt-react-class mbr/ComponentName))
[:> mbr/ComponentName]without my wrapper, but I am going to provide additional components and I don’t want them to have to remember which are raw React and which are higher level. At runtime I can do emit vectors of
[symbol component]like this:
is it possible to do something similar in a macro and emit something like
(ns example (:require ["mathbox-react" :as MB] [reagent.core :as r])) (def sym->component (doseq [[k v] (.entries js/Object MB)] [(symbol k) (r/adapt-react-class v)]))
(def ~(symbol k) ~(r/adapt-react-class v))?
You can definitely run some JS code within JVM, but that would mean bringing in some extra dependencies for compile-time. This is the commit where shadow-cljs removed similar functionality: https://github.com/thheller/shadow-cljs/commit/6daffeae50d0b7f029aad8e975997b20223955dc It might be tricky to make it work with an NPM dependency, although documentation suggests that it should be straightforward: https://www.graalvm.org/22.1/reference-manual/js/Modules/
FWIW, a similar wrapper went with a direct approach - all the symbols are already there in the code: https://github.com/arttuka/reagent-material-ui
Apart from being the most straightforward implementation, it also gives its user all the static code inspection niceties.
And you don't have to write everything by hand - you can have a CLJS script that generates those
(def ...)s for you, which you would then commit into a repo.
Actually, definitely go with the second approach. Because if you gather everything under a single umbrella namespace, DCE will not be possible. An NPM dependency, once required in a loaded namespace, will not be removed - even if you don't use it.
In the case of
arttuka/reagent-material-ui, notice how the author puts every components in its own namespace. You don't want to load a million of icons or whatever just because you needed a single number input field.
interesting, that makes sense. in this case all components live in a single file: https://github.com/ChristopherChudzicki/mathbox-react/blob/main/src/components/components.tsx
@U2FRKM4TW how would you deal with an import of this components.tsx to allow DCE?
for example maybe one namespace per components, but then
["mathbox-react/path/to/components" :refer [SpecificComponent]] in each namespace? would that do it?
or is this a change that the mathbox-react library author should address upstream, with separate files for each component
> how would you deal with an import of this components.tsx to allow DCE?
As far as I know, that would not be possible without refactoring the
:refer doesn't cut it. It has to be its own namespace. When you use
:refer, the whole mentioned JS file is still loaded.
As a piece of reference: https://shadow-cljs.github.io/docs/UsersGuide.html#_using_npm_packages Specifically, the rest of the section starting at "Notice that previously we were stuck using bundled code".
okay I can push that upstream, that is helpful. I’ll do the right thing in this library and then get that change pushed up. you noted that I could write a cljs script to generate each def; that will let me pull in docstrings too so that’s actually quite nice. the idea is to have the script actually populate the file tree yeah?
Could even put it into a Git hook and make sure that there are no changes to the generated files before you commit.
Just to guarantee that your CLJS code is always in sync with whatever NPM library version you depend on.
FINAL QUESTION while I have you: I named the library
mathbox-cljs, which is a touch awkward. My thought was that, because there is an npm dependency pulled in with the name “mathbox”, that it would be good to disambiguate.
If I DID make namespaces like
(ns mathbox.blah) , would the compiler become confused with the
typing this out I guess that would only be a problem with a bare
mathbox namespace at the top level.
so maybe this is actually a question about “is there any good reason to add that suffix”, since it would be definitely clearer for the user to remove it
I don't think there's a good reason, unless, as you say, you decide to use a single-level
Just to be sure, I'd check that
mathbox.blah doesn't intersect with
"mathbox/blah" (of course, you have to find what JS package you can import, and then create a corresponding CLJS namespace). And you'd also have to check with different build tools since AFAIK they resolve or might resolve NPM dependencies differently.
But I'm 90% certain that it's not an issue at all.
yeah, that would be the issue I’d anticipate, that if I want to mirror mathbox’s tree I’ll end up with clashes. But now that I look, mathbox has all of those nested under “primitives/types”: https://github.com/unconed/mathbox/blob/master/src/primitives/types/operator/grow.js so I won’t clash.
Even if there was a name clash, my intuition suggests that
mathbox would be first checked at
"mathbox" would be first checked at
mathbox.js. But maybe it's wrong, although I'd be surprised.
Advice needed. How would you implement bit masks in clj and cljs when they definitely won't fit in a single int? I think about int-array but maybe there is a better approach.
My first step would be to consider very carefully whether I truly need a bit mask or whether some other approach would work, like a map with boolean values.
If the conclusion is that a bit mask is the only approach, then I'd probably use
js/BigInt with CLJS and
BigInteger with CLJ.
In Java, https://docs.oracle.com/javase/8/docs/api/java/util/BitSet.html is probably good to consider, not sure if there is a js equivalent
Ah, thanks. I kept thinking that there was a specific class for this but couldn't remember it. And seems like there are a few JS libraries to mimic that functionality.
Thank you guys! I want a single implementation for both languages, so it seems like int with fallback to int-array is the only option.
It'd still go with
BigInteger then because they both support bitwise operations.
Ints are different between JS and Java - you can't just use them without writing at least some platform-specific code.
> writing at least some platform-specific code. Yeah, I know. Svelte is a reference implementation for my problem. Have checked and they are using arrays of *ints, not even bigints.