This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2023-03-07
Channels
- # announcements (20)
- # babashka (25)
- # beginners (48)
- # biff (26)
- # calva (5)
- # cider (3)
- # clara (7)
- # clerk (7)
- # clj-kondo (61)
- # cljdoc (3)
- # clojure (6)
- # clojure-austin (1)
- # clojure-conj (8)
- # clojure-europe (58)
- # clojure-nl (1)
- # clojure-norway (4)
- # clojure-poland (1)
- # clojure-uk (9)
- # cursive (2)
- # emacs (11)
- # fulcro (8)
- # graphql (14)
- # gratitude (6)
- # humbleui (10)
- # hyperfiddle (17)
- # integrant (15)
- # introduce-yourself (1)
- # leiningen (5)
- # malli (13)
- # meander (21)
- # nbb (11)
- # off-topic (15)
- # pedestal (15)
- # polylith (15)
- # quil (28)
- # rdf (2)
- # reitit (3)
- # releases (6)
- # sci (21)
- # shadow-cljs (38)
- # spacemacs (3)
- # xtdb (6)
I'm making a JS lib from a CLJS lib, using :target :esm
. This CLJS lib is using React/Reagent and the JS lib is meant to be used within a React app. But the JS lib is consumed via CDN, rather than using webpack or similar, since multiple apps all use it and I need them on the same version. Will the duplicate React code lead to issues here? And is there a way around this with shadow-cljs?
My big concern here is whether reagent components can be consumed from “vanilla React” given that reagent structures props and rendering in a very different way to most other React components. (i.e. while we can re-use react components in reagent, we cannot necessarily re-use reagent components in react)
I am mostly basing my comments off of remarks made https://clojurians.slack.com/archives/C0620C0C8/p1675329221577859?thread_ts=1675296130.694469&cid=C0620C0C8 and https://clojurians.slack.com/archives/C0620C0C8/p1675762484239369?thread_ts=1675296130.694469&cid=C0620C0C8
Yup — that same link was posted in the thread I referenced, but apparently it’s only for use within a reagent app
The good news is that you will have some luck with Helix, whose components are always plain old React components. This makes them very natural to embed into vanilla JS and even in react components that let you pass in a component (e.g. material ui's list component, which accepts a list item prop if you want to bring your own list item component)
in that case i think your distribution issues can be solved by deciding a minimum react version (e.g. 16) and building against it — I don’t think react has to be bundled in this case, but users of your library will have to be aware of compatible react versions
Hm, my CLJS lib is already built with React. Extracting from a CLJS app, to make the functionality available to other JS apps.
Seems like I'd need to rewrite the views I want to share in Helix. Maybe all of them, if Helix can't coexist with Reagent.
Helix can coexist with reagent just fine. The caveat is that reagent views are functions returning hiccup, which need to be interpreted into a react component. This is done with r/as-element
I want to say the bigger concern here is being able to refactor Hiccup in a way that plays nicely with Helix, assuming you’d want to refactor reagent code into helix code. I believe Helix lets you define your own defnc
macro so that you can use Hiccup, but it’s an “opt in” feature and it needs some work to set up
Thanks for the info. This was quite the surprise. That reagent fn's docs could really be more clear that it's not creating react components that can be used in a react app.
you could use :js-options {:js-provider :import}
https://shadow-cljs.github.io/docs/UsersGuide.html#_third_party_tool_integration
and if the other app provides an import map, it could provide the react version it uses that way? https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script/type/importmap
or :js-options {:keep-as-import #{"react" "react-dom"}}
to only keep those two as regular import
but have the rest bundled also works
it really all depends on how the react app you are trying to integrate with is built
it could also be providing a global React
variable, where you'd do this https://shadow-cljs.github.io/docs/UsersGuide.html#js-resolve
FWIW you can use reagent components from react directly just fine. just needs to be the reactify-component thing, not the plain fn
but even the plain fns will work if you wrap them as (defn my-component [props] (r/as-element [the-actual-thing ...]))
Hey everyone, newbie question, I'm starting my first project with cljs
, I use npx create-cljs-project
command to create my project, I want to use react also so I did a yarn add react
, but I didn't find on the docs any example of a initial file setup to run my project with a simple "Hello World" div. When I try to yarn shadow-cljs watch app
(I setup the app :build
on shadow-cljs.edn
) and I access on my browser the :port
I setup on the shadow-cljs.edn
I got an error: ERROR: java.lang.ArithmeticException: long overflow
could anyone please point me some example or some guide on how to setup correctly react on my project? A example project would be nice so I can see how things are made on a real project. Thx in advance. 🙂
maybe you want to start with https://github.com/shadow-cljs/quickstart-browser
create-cljs-project is the bare minium, without any assumption that you are even going to build a web frontend
Thx, I was refering to the nrepl
port, but I saw that maybe I need to setup the dev-http
instead. I'll take a look on that project after lunch
With that project and https://maksimrv.medium.com/setup-shadow-cljs-react-project-36a14e9f07d5 now everything works properly 🙂 I can run, the auto-refresh worked well and also react is working. Thanks again, awesome project
please don't do this 😛
(defn main []
(let [app-node (.getElementById js/document "app")]
(rdom/render [app] app-node)))
(main)
instead do
(defn main []
(let [app-node (.getElementById js/document "app")]
(rdom/render [app] app-node)))
(defn ^:dev/after-load reload! []
(main))
see https://code.thheller.com/blog/shadow-cljs/2019/08/25/hot-reload-in-clojurescript.html
hmm makes sense to use lifecycle, I'll read ASAP, thank you