clojurescript

ClojureScript, a dialect of Clojure that compiles to JavaScript http://clojurescript.org | Currently at 1.10.879
2021-05-21T00:00:09.121100Z

@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. πŸ™‚

2021-05-21T00:02:37.121300Z

Oh wait, that's just because the webpack bundle had co-dependencies. Never mind.

Mateusz Mazurczak 2021-05-21T09:24:41.122800Z

Fulcro has similar approach, although it has high entry treshold so you will need to spend some time grasping the concepts. It is worth the time in my opinion. Also here on slack is #fulcro channel, https://fulcro-community.github.io/guides/tutorial-minimalist-fulcro/ and the author of fulcro made https://www.youtube.com/watch?v=wEjNWUMCX78&list=PLVi9lDx-4C_T7jkihlQflyqGqU4xVtsfi or https://book.fulcrologic.com/

Lu 2021-05-21T09:37:11.124200Z

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 ??? ..
    ))

Jakob Durstberger 2021-05-21T09:47:40.124700Z

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))

p-himik 2021-05-21T09:53:05.124900Z

It might be needed for some API. If so, you should be able to just create a record.

p-himik 2021-05-21T09:53:42.125100Z

And if you really need a JS class and you're using shadow-cljs, check out shadow.cljs.modern/defclass.

Lu 2021-05-21T09:56:44.125400Z

@jakob.durstberger Tried that already.. it’s returning the full html as a string in the view

Lu 2021-05-21T09:57:17.125600Z

@p-himik yeah I am using shadow-cljs.. will check out shadow.cljs.modern/defclass

p-himik 2021-05-21T09:57:38.125800Z

See if you can use a regular defrecord first - way less hassle.

1πŸ‘
emccue 2021-05-21T15:33:49.148500Z

@lucio also you don't need to neccesarily create a named type if you never dispatch on it

emccue 2021-05-21T15:38:23.151200Z

(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))

Tomas Brejla 2021-05-21T15:39:19.151600Z

Hello. I'm trying to create a small pet project in cljs (`reagent`, reframe, react-leaflet) + cljbackend (`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-mainmight 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 πŸ”₯πŸ€žπŸ™‚

emccue 2021-05-21T15:39:36.151800Z

then you use the namespace as your "object boundary"

emccue 2021-05-21T15:39:47.152Z

and the exposed functions as your "methods"

Tomas Brejla 2021-05-21T15:40:07.152200Z

Btw since I've asked quite a lot of questions, I guess it's better to discuss them here in 🧡

emccue 2021-05-21T15:40:25.152500Z

protocols, actual js classes, etc, are mostly useful for interop or dynamic dispatch

emccue 2021-05-21T15:40:51.153100Z

you can add in dynamic dispatch to this scheme later by making public functions be protocol functions

dnolen 2021-05-21T15:41:10.153600Z

@brdloush there are variety of tools - pretty much anything could be accomplished with any of them

dnolen 2021-05-21T15:42:04.154500Z

however note that everything you could possibly want to do can be accomplished w/ just ClojureScript by itself

emccue 2021-05-21T15:42:16.154900Z

but if you don't need it, don't add it

dnolen 2021-05-21T15:43:27.155800Z

like the base feature of using libs from npm etc.

dnolen 2021-05-21T15:44:14.156700Z

that said - you might want a hot-reloader - and that's all you want over ClojureScript - then Figwheel suffices

dnolen 2021-05-21T15:44:52.157400Z

it does provide a bunch of other things, like RN integration, many knobs specific to it's operation

dnolen 2021-05-21T15:45:23.158200Z

but maybe you want a more complete build tool and you don't care about a deps.edn centric workflow

dnolen 2021-05-21T15:45:39.158600Z

then shadow-cljs may be more to your taste

dnolen 2021-05-21T15:47:50.160900Z

or say you want React Native and you don't care about options

dnolen 2021-05-21T15:48:04.161500Z

you have only one goal - React Native - then Krell does only that

dnolen 2021-05-21T15:48:12.162Z

and has docs you can read in 2 minutes

dnolen 2021-05-21T15:48:34.162600Z

and no interesting configuration of any kind to understand

emccue 2021-05-21T15:48:42.162800Z

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

Tomas Brejla 2021-05-21T15:50:22.164300Z

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.

Lu 2021-05-21T15:58:35.164400Z

Thanks! I’d need to pass the class as an argument so not sure that would work

dnolen 2021-05-21T16:05:22.165500Z

@brdloush you cannot really eliminate NPM - React comes from there etc.

dnolen 2021-05-21T16:06:24.166Z

and cljsjs continues to exists to support older projects - but NPM for these kinds of deps is preferred

dnolen 2021-05-21T16:08:41.167700Z

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

Christopher Gsell 2021-05-21T16:12:23.170700Z

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?

dnolen 2021-05-21T16:28:06.171200Z

@cgsell why don't they work? If they are React components they should work just fine

Tomas Brejla 2021-05-21T16:44:31.171500Z

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)

thheller 2021-05-21T17:24:03.171900Z

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

thheller 2021-05-21T17:24:40.172100Z

(which is more complicated as you experienced)

thheller 2021-05-21T17:24:47.172300Z

but I'm obviously biased πŸ˜‰

2πŸ™‚
emccue 2021-05-21T17:34:46.172600Z

to some javascript code?

dnolen 2021-05-21T18:04:51.174200Z

@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

1πŸ‘
dnolen 2021-05-21T18:05:34.174700Z

let JS tools handle JS problems and everything will work and all JS documentation is true for ClojureScript usage as well

Endre Bakken Stovner 2021-05-21T18:08:53.174800Z

Thanks! Appreciate all the help. Also, I've realized that I can't get by blindly trying stuff so I've started reading about React, Cljs and D3.

Lu 2021-05-21T18:20:54.176300Z

Yup as a value of a JS object :)

Endre Bakken Stovner 2021-05-21T18:25:14.180100Z

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]]))

grounded_sage 2021-05-21T18:27:28.180500Z

anyone got experience with the Monaco editor library?

Endre Bakken Stovner 2021-05-21T18:58:21.183Z

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?

BuddhiLW 2021-05-21T19:04:00.183500Z

You can use also (.. js/document f1 f2 f3 ...) equal to js/document.f1.f2.f3 So, (.. dag (idescendants) (entries)) Should work

Endre Bakken Stovner 2021-05-21T19:05:17.183700Z

Thanks. That is an even nicer way to put it. But I still get the inference problem mentioned above πŸ™‚

emccue 2021-05-21T19:19:21.183900Z

@endrebak85 Type hint with ^js

emccue 2021-05-21T19:20:04.184100Z

it just needs to know to not mangle it in advanced compilation, not the exact set of methods available

1πŸ™
thheller 2021-05-21T19:23:59.184400Z

I created an example yesterday which pretty much applies 1:1 to your case https://github.com/thheller/reagent-pdfjs

thheller 2021-05-21T19:24:24.184700Z

instead of a :canvas you create a :svg element

thheller 2021-05-21T19:24:58.185Z

and you then do (d3/select (.-current svg-ref))

thheller 2021-05-21T19:25:15.185200Z

the update-wrapper you call in the useEffect callback

thheller 2021-05-21T19:27:07.185400Z

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

grounded_sage 2021-05-21T19:43:47.188800Z

nvm I figured out my error when I posted here haha. Had a typo. πŸ˜…

Endre Bakken Stovner 2021-05-21T19:51:35.189Z

Much appreciated!

Endre Bakken Stovner 2021-05-21T19:51:50.189200Z

Thanks to you too πŸ™‚

Christopher Gsell 2021-05-21T19:56:06.192Z

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”

Tomas Brejla 2021-05-21T20:33:29.192200Z

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.

thheller 2021-05-21T20:36:03.192400Z

that is what shadow-cljs was made for πŸ˜‰

Tomas Brejla 2021-05-21T20:36:06.192600Z

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 πŸ‘ .

thheller 2021-05-21T20:36:44.192900Z

ask away, I'll answer when I have time πŸ™‚