Fork me on GitHub
#clojurescript
<
2021-08-19
>
gdubs15:08:02

I'm using a clojurescript repl through emacs + cider. Whenever I do a println from a not-immeditaly-resolved promise, the output gets lost (e.g. doesn't show up in the repl). The snippet below demonstrates this and is from the promesa docs. If I change the delay to 0, I see the expected output in the repl. If I run the cljs script from the cli, I also see the output. Any ideas? Or any pointers on where the culprit may be? There's a lot of elements in play here: emacs, cider, shadow-cljs, promesa, cljs compiler, etc, etc.

p-himik15:08:37

Does the output appear in the JS console?

gdubs15:08:13

If by JS console you mean in the brower, this is.a nodejs app. Is there typically a sperate JS console from what I see in the repl? js/console.log things end up in the repl.

p-himik16:08:09

No idea then, I have never tried running CLJS on NodeJS. js/console.log can easily be overwritten by the REPL machinery to specifically print into REPL. println calls cljs.core/*print-fn* to do the actual printing, which can also be overwritten by the REPL machinery - only this time not globally but on a per-call basis. Meaning, the default value of cljs.core/*print-fn* is something that doesn't print to the REPL.

p-himik16:08:42

Maybe something like this could shed some light:

(def orig-print-fn (atom nil))

(-> (p/delay 1000 "")
    (p/then (fn [_]
              (reset! orig-print-fn cljs.core/*print-fn*))))

;; Wait for one second
@orig-print-fn

thheller16:08:50

the shadow-cljs node-repl should capture all output

thheller16:08:14

the node repl available for :node-script or :node-library builds does not, so there async output just goes to stdout not the REPL

thheller17:08:15

dunno where emacs shows that

thheller17:08:25

which REPL do you use?

gdubs18:08:04

@U05224H0W I'm 'jacking in' and then selecting shadow and node-repl. Does that answer your question?

gdubs18:08:05

@U2FRKM4TW when I run your suggestion, @orig-print-fn shows me the same symbol as cljs.core/*print-fn*

gdubs18:08:19

that is, #object[shadow$cljs$devtools$client$env$set_print_fns_BANG__$_repl_print_fn]

gdubs18:08:23

@U05224H0W my target is :node-script

gdubs18:08:38

> the node repl available for `:node-script` or `:node-library` builds does not, so there async output just goes to stdout not the REPL I think you're describing what I'm seeing? My async output is going somewhere where I can't see it, but my sync output is going to the repl.

gdubs18:08:43

then again, when I jack in, I don't select my specific target, :app, but select node-repl. 🤷

thheller19:08:04

with node-repl you should see it but I don't have a clue regarding the emacs side

thheller19:08:14

shadow-cljs node-repl you should be seeing the output

gdubs20:08:51

☝️ confirmed! it was helpful for me to at least narrow it down to a emacs/cider/nrepl issue. now I have a smaller area to investigate.

gdubs15:08:20

Interesting wrinkle: When I 'jack in' from emacs, I loose the async println's, but when I start the repl from the cli using npx shadow-cljs -d nrepl/nrepl:0.9.0-beta1 -d cider/piggieback:0.5.2 -d cider/cider-nrepl:0.26.0 node-repl and then use emacs to connect to the existing repl, I don't loose the async messages. (They show up in both the emacs repl and on the cli, the former being very convenient)

thheller16:08:39

sorry don't have a clue regarding any emacs/cider stuff. node-repl should always give you all the output but all shadow-cljs can do is send nrepl messages for those. where or how cider displays them I don't know

Ryan17:08:02

I'm trying to add a UI component library (primereact) into a re-frame project but it can't find the dependency to import.. I've been added via yarn, do I also need to add it to, say, shadow-cljs.edn?

thheller17:08:53

is it a npm library or cljs?

thheller17:08:03

then just yarn should be enough

Ryan17:08:20

ok, I thought so.

Ryan18:08:27

Ok, so added it to yarn, tried to require it [primereact :as pr] and get The required namespace "primereact" is not available, it was required by "proj/views.cljs".

emccue18:08:49

try "primereact"

emccue18:08:58

as a string

Ryan18:08:22

Aha, one error closer: The required JS dependency "primereact" is not available, it was required by "pnx_web/views.cljs".

Ryan18:08:19

Ok, I think there's no top-level thing to import, it looks like you import per-component, so importing "primereact/button" :as pr-button worked, its just giving me guff here: Warning: React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: object.

Ryan18:08:28

but I think I'm at least past the import problem 🙂 thanks!

p-himik18:08:10

It still seems to be the import problem, but you have advanced a step more. Take a look at this section: https://shadow-cljs.github.io/docs/UsersGuide.html#_using_npm_packages

Ryan18:08:58

Thanks.. I've gotten decently familiar with (basic) clojure, and can write angular/react apps all day long, but definitely getting tripped up in the space between at the moment! 🙂

ajl18:08:35

Hi there! I'm trying to learn clojurescript (and clojure!), and I'm having trouble getting things up and running. I compile my .cljs file using lein-cljsbuild, then I import the build code into an .html file using script tags. It seems like the main file cljsbuild generates is inert, though. It's just a bunch of calls to 'goog.addDependency'. I can import 'js/goog/base.js' first, and that allows the code to run without error, but nothing happens. I can then import my script, but I get errors because my dependencies aren't available. I'm pretty sure I need to do something to tell 'goog' to run my script for me, but I can't find any documentation on how to do that. I've read quite a few tutorials and documentation, but I can't find anything that addresses how to run clojurescript code once I've built it, which makes me feel like I'm going crazy.

p-himik18:08:24

goog.addDependency without any substance sounds like you're building a development build, not a release one. But maybe that's what you want. In either case, when you have the main entry point in your script, you have to call it somehow. There are multiple ways, and at least shadow-cljs has something specific to it. But on can override window.onload, you can export the function and call it explicitly in a separate <script> tag, or maybe even just call it at the end of the same script where it's defined (probably not great for hot-reloading your code).

p-himik18:08:55

Just in case it will look familiar to what lein-cljsbuild has, here's how it would look in shadow-cljs, notice that :init-fn key: https://shadow-cljs.github.io/docs/UsersGuide.html#_preparing_the_app

ajl18:08:52

I was trying

(set! (.-onload js/window) (fn []
    (js/console.log "onready was called")
    (rdom/render [some-component] (js/document.querySelector ".app"))))
but a bunch of libraries I use weren't defined. It turns out, I was missing a compiler flag, :main "clojure-learning.client" , which tells cljsbuild to compile this as an exe and not a library, basically. I added that flag, and now the main.js file looks totally different and runs my code with the correct dependencies imported.

ajl18:08:02

Also, I was ignoring 'shadow-cljs' because I assumed it was a shadow-dom thing, and I didn't care. Now that I see it's a clojurescript build tool, I'll definitely take a look at it.

👍 3
winsome21:08:34

We've got a library written in clojurescript and I'd like to generate typescript annotations for people using it from typescript-land - has anyone done that before?

emccue22:08:55

yes and no - I remember someone was trying to do something similar in #malli recently