@smith.adriane Welp, so I can get it to evaluate javascript just fine, although if that javascript is a compiled webpack thing, then it complains. So shrug. π
Oh wait, that's just because the webpack bundle had co-dependencies. Never mind.
How should I go about converting this to cljs?
class CustomHeader {
init(agParams) {
this.agParams = agParams;
this.eGui = document.createElement('div');
this.eGui.innerHTML = `<div>foo</div>`;
}
getGui() {
return this.eGui;
}
}
What Iβve got so far is:
(defn CustomHeader
[]
(this-as ^js this
;;??? init??? ...
(set! (.-eGui this) (js/document.createElement "div"))
(set! (-> this .-eGui .-innerHTML) "<div> foo </div>")
;;??? getGui ??? ..
))
Can this just be a function that returns the div?
The agParams
seem to be unused anyway
(defn custom-header []
(let [e-gui (.createElement js/document 'div)]
(.innerHTML e-gui "<div>foo</div>")
e-gui))
It might be needed for some API. If so, you should be able to just create a record.
And if you really need a JS class and you're using shadow-cljs, check out shadow.cljs.modern/defclass
.
@jakob.durstberger Tried that already.. itβs returning the full html as a string in the view
@p-himik yeah I am using shadow-cljs.. will check out shadow.cljs.modern/defclass
See if you can use a regular defrecord
first - way less hassle.
@lucio see https://clojureverse.org/t/modern-js-with-cljs-class-and-template-literals/7450
@lucio also you don't need to neccesarily create a named type if you never dispatch on it
(ns custom-header)
(defn init [ag-params]
(let [e-gui (doto (.createElement js/document "div")
(set! .-innerHTML "<div> foo </div>))]
{::ag-params ag-params
::e-gui e-gui}))
(defn get-gui [custom-header]
(::e-gui custom-header))
Hello. I'm trying to create a small pet project in cljs
(`reagent`, reframe
, react-leaflet
) + clj
backend (`cruxdb` , integrant
, reitit
). I'm also using deps.edn
for dependencies, no leiningen.
I originally started using shadow-cljs
for building/developing the cljs frontend and everyhing was working just fine. Then I wanted to try (just being curious) how figwheel-main
would work for the same project. It took me quite a while to set it up, but in the end it's somehow working. I had to provide custom externs (based on generated inferred_externs.js
+ few more manual entries for leaflet.js).
I'm still not sure which of the two build tools to stick with. I've found this question https://ask.clojure.org/index.php/10403/pros-and-cons-figwheel-vs-shadowcljs which seems to indicate that figwheel-main
might be less complex and basically a "thinner wrapper" around cljs compiler itself. If using one of the tools means that I'll have to learn more useful things, I don't mind investing more time into it.
So my questions are..
1. Since the heart of my app is leaflet.js
map (and I want to be using reagent
+`reframe`), I guess NPM's react-leaflet
is a way to go (or is there any better option?). When it comes to NPM support, can either figwheel
or shadow
be considered a "better choice" or both provide similar level of support?
2. Is it normal that I had to deal with inferred + manual externs when using figwheel-main
, while I didn't have to deal with externs at all when I was using shadow
? I might have done some stupid mistake when switching to figwheel-main
, not sure.
3. Does relying on npm libs when using figwheel-main
mean that it have to be using webpack
internally? If so, how much details of webpack
do I need to learn to efficiently use it?
4. I noticed that the "production" js-bundle generated by figwheel-main
(with advanced optimizations) is way larger (1.1MB) than the production js generated by shadow
(724kb). Is there any good way to easily find out what gets included in those optimized js builds?
5. are http://cljsjs.github.io/ libraries still relevant or they should no longer be needed?
Any hints/help/ideas appreciated. And please no flame π₯π€π
then you use the namespace as your "object boundary"
and the exposed functions as your "methods"
Btw since I've asked quite a lot of questions, I guess it's better to discuss them here in π§΅
protocols, actual js classes, etc, are mostly useful for interop or dynamic dispatch
you can add in dynamic dispatch to this scheme later by making public functions be protocol functions
@brdloush there are variety of tools - pretty much anything could be accomplished with any of them
however note that everything you could possibly want to do can be accomplished w/ just ClojureScript by itself
but if you don't need it, don't add it
like the base feature of using libs from npm etc.
that said - you might want a hot-reloader - and that's all you want over ClojureScript - then Figwheel suffices
it does provide a bunch of other things, like RN integration, many knobs specific to it's operation
but maybe you want a more complete build tool and you don't care about a deps.edn
centric workflow
then shadow-cljs may be more to your taste
or say you want React Native and you don't care about options
you have only one goal - React Native - then Krell does only that
and has docs you can read in 2 minutes
and no interesting configuration of any kind to understand
using namespaced keywords there makes it clear to other bits of code that they shouldn't be looking into those map keys - it can be a convention for stuff being "private" if you want
I don't need any RN support, my app needs to be just a regular webpage (so that it can be embedded as a "webpage widget" into another native android app). I basically want to use reagent, reframe, and leaflet.js. And yes, hot-reloading is something that I definitely like to use. Not planning to use any more npm libs, so if there's some way of eliminating the need of npm and use more "cljs-only" way, I'm totally interested.
Thanks! Iβd need to pass the class as an argument so not sure that would work
@brdloush you cannot really eliminate NPM - React comes from there etc.
and cljsjs continues to exists to support older projects - but NPM for these kinds of deps is preferred
going back a bit 1. matter of taste 2. seems strange 3. you have to setup manage webpack yourself w/ ClojureScript ... Figwheel hrm probably does it internally now? 4. did you gzip to see what the final difference is 5. cljsjs is still useful but not recommended
I am starting a new clojurescript project and in the past have used Evergreen UI as the react framework. It seems like there have been big adjustments though since I last used it as many of the elements donβt work with reagent. Is there another UI framework that people have had success using?
@cgsell why don't they work? If they are React components they should work just fine
3) yes, fighweel-main mentions that in its documentation, that you should enable webpack via ^{:auto-bundle :webpack}
metadata in their edn config. I just don't understand whether it's needed or not. Somehow I thought that all that webpack might not be needed as clojurescript compiler itself seems to have support for npm via :npm-deps
. So I was hoping to avoid webpack
(as I don't know it) unless really needed. For me, it's "the fewer moving parts (and magic) the better" π
4) the gzipped sizes are: 196K from shadow
, 289K from figwheel-main
. Not much of a difference, but still it's interesting, as I'm expecting similar compilation process (and optimizations) should be triggered by both figwheel and shadow. Perhaps those manually provided externs might be the cause. The auto-generated inferred_externs.js
has 110 entries and I had to manually add a few more for leaflet's L.Map
and L.map
(such as L.map.flyTo
, L.map.on
etc)
IMHO this argument about figwheel being "thinner" is nonsense. You'll end up setting up the same things anyways. shadow-cljs you just get it all out of the box instead of setting up the pieces individually
(which is more complicated as you experienced)
but I'm obviously biased π
to some javascript code?
@brdloush fwiw I don't personally believe in avoiding Webpack and JS build tools - shadow-cljs works w/ this way and it does work for a lot of folks - but the JS ecosystem is wide and by punting the problem, more libraries and library patterns can be supported
let JS tools handle JS problems and everything will work and all JS documentation is true for ClojureScript usage as well
Yup as a value of a JS object :)
Newb q: If I have a component (`#wrapper`) I want to update with a function (`update-wrapper`), what is the correct place to call that function?
(defn update-wrapper []
(let [svgSelection (d3/select "#wrapper")
;; do lots of things to svgSelection ...
(defn home-page []
(let [_ (update-wrapper)] ;; probably should not call the function here as the div#wrapper is not rendered yet
[:section.section>div.container>div.content
[:div#wrapper]]))
anyone got experience with the Monaco editor library?
I am surely doing something stupid, but... I want to translate the following call chain:
dag.idescendants().entries()
My attempt:
(-> dag (.idescendants) (.entries))
This gives the error Cannot infer target type in expression (. dag idescendants)
.
I see that https://clojurescript.org/guides/externs#externs-inference, but the typeof
the objects is only object
, not anything informative like js/Foo.Bar
. What do I do?https://lwhorton.github.io/2018/10/20/clojurescript-interop-with-javascript.html
You can use also (.. js/document f1 f2 f3 ...) equal to js/document.f1.f2.f3 So, (.. dag (idescendants) (entries)) Should work
Thanks. That is an even nicer way to put it. But I still get the inference problem mentioned above π
@endrebak85 Type hint with ^js
it just needs to know to not mangle it in advanced compilation, not the exact set of methods available
I created an example yesterday which pretty much applies 1:1 to your case https://github.com/thheller/reagent-pdfjs
instead of a :canvas
you create a :svg
element
and you then do (d3/select (.-current svg-ref))
the update-wrapper
you call in the useEffect
callback
you can use webpack perfectly fine with shadow-cljs if you want to. doesn't negate any of the other stuff shadow-cljs offers. shadow-cljs handling npm for you is just the default, but switching it is trivial
nvm I figured out my error when I posted here haha. Had a typo. π
Much appreciated!
Thanks to you too π
So in version 4.0 of evergreen I can call different elements no problem. In 6.0 I call the same elements and get a blank screen with error βTypeError: inline_style_prefixer_1.prefix is not a functionβ
The thing is that I have no idea yet if I want or even need to use webpack or not. I've been doing mostly backend (mostly java and occasionally a little clojure) development in last decade. So I don't know much about webpack and whether I need it or not really. What I do know is that using shadow-cljs
was super-easy and I didn't have any major issues.
So I guess I'm switching back to shadow-cljs
for now π. It's not that I wouldn't like to learn more about figwheel-main
, internals and options of clojurescript compiler etc. But I like that shadow-cljs
just works. Which means that I can focus on learning those bits and pieces which directly relate to the app that I'm trying to build.
that is what shadow-cljs was made for π
Thanks for the link @thheller. I guess I might have some more questions regarding shadow-cljs later, so I'm joining #shadow-cljs. But I'll try to deal with those issues myself first as there's quite a lot of good documentation for shadow π .
ask away, I'll answer when I have time π