Fork me on GitHub
#shadow-cljs
<
2022-03-30
>
thheller06:03:48

@dam which :target?

lambdam06:03:25

Node.js. My intent is to set up a reloaded workflow, as I would with integrant or juxt/clip on the JVM. Is it common to use those libraries on Node.js/shadow-cljs projects ? By the way, we're aiming using a Lambda service (Scaleway for the time being) with Node.js runtime.

thheller07:03:57

@dam which shadow-cljs :target in your build config https://shadow-cljs.github.io/docs/UsersGuide.html#target-node :node-script or :node-library?

lambdam07:03:51

Ah sorry. :node-script

thheller07:03:33

then the REPL should work fine. the docs have an example for hot-reload

lambdam07:03:46

Yes. I copied/pasted it and it doesn't reload the code. I'm using Calva on VSCode. I declared the build like so :

{...
 :builds
 {:back-dev {:target :node-script
             :main myproject.back.core/back-main
             :output-dir "build/back"
             :output-to "build/back/main.js"}
  ...}}
Then I run the jack-in command which runs npx shadow-cljs -d cider/cider-nrepl:0.27.4 watch :back-dev Then I'm asked to choose a "Project type" (all :builds entries are present). I select shadow-cljs. Then I'm asked to "select builds to start". I choose only :back-dev Then I'm asked to "select which build to connect to". I have all builds as options plus node-repl and browser-repl. When I select :back-dev, I get a No available JS runtime. When I select node-repl, I can evaluate my code but the hot reloading as describe in the documentation doesn't work. I tried all options : inline ^:dev/before-load and ns ^:dev/always or in the config file. with :autoload set to true. I can't see any callbacks executed nor new définitions containing new values. Do you think that it might be a Calva problem or a shadow configuration problem on my side? Thanks a lot.

thheller09:03:11

if you pick node-repl that is a purely standalone REPL. it does not do hot reloading and is not coupled to your build

thheller09:03:32

if you pick :back-dev that is your project. you just actually need to run it to get a REPL

thheller09:03:46

so node build/back/main.js in another terminal or so

lambdam13:03:58

All riiight. Thanks a lot. I found the entry in the documentation that refers to this. https://shadow-cljs.github.io/docs/UsersGuide.html#_start_the_repl Adding the information that you gave me to point #2 would help I think. I didn't find any repo for the documentation. I can take time to contribute with a PR if there is any.

lambdam13:03:04

Thanks again !

thheller07:03:51

reloaded workflow in general is a bit trickier since everything is async. but should be fine. don't think its common to use integrant for CLJS, don't think I know anyone that does

thheller07:03:09

most people tend to use clojure on the server side

olaf07:03:25

How I can resolve a npm library inside a macro? I’m writing a macro like this one inside a .cljc file

(ns kol.macros
  #?(:cljs
     (:require-macros [kol.macros :refer [deftheme]])
     (:require ["@codemirror/view" :refer [EditorView]])))

(defmacro deftheme [name theme]
  #?(:cljs
     `(def ~name
        (.theme EditorView (clj->js ~theme)))
     :clj nil))

(comment
  (macroexpand
   '(deftheme darko {:.cm-content {:caret-color "cursor"}}))
and is expanded like this
(def darko (.theme kol.macros/EditorView (kol.macros/clj->js {:.cm-content {:caret-color "cursor"}})))
but instead of resolving EditorView as kol.macros/EditorView I need to point to the npm library

lambdam08:03:39

@U01UYD2CL10 macros are never executed on cljs side so the conditional inside doesn't make sense (as far as I know) You could try to include the symbol as is. Try this:

#?(:clj
   (defmacro deftheme [name theme]
     `(def ~name
        (.theme ~'EditorView (clj->js ~theme))))

olaf08:03:53

Thanks @dam but is not working as expected

thheller09:03:28

you could just make this a function

(def darko (theme {:.cm-content {:caret-color "cursor"}}))

thheller09:03:21

a macro can't access JS deps directly but you can make a helper function in the kol.macros ns that does the above basically. ie. create a helper function that calls the npm dep

thheller09:03:39

you can also reach into the analyzer to get the JS dep alias but that is not recommended

olaf09:03:17

I made a simple function create-theme , thanks!

dergutemoritz07:03:15

Hi! Is there a way to pass args to the main of a :node-test build (which has :autorun true) when watching it? What I would like to do is run only a subset of the tests on rebuild which would be possible by passing a --test option to the default main. Alternative solutions welcome, too, of course 🙏

thheller09:03:42

@dergutemoritz that is not supported no. you can always run the tests in the REPL

dergutemoritz07:03:59

Thanks! What would be the recommended way of doing that? It seems like :node-test doesn't support connecting a REPL so I would have to have an equivalent :node-library build for that purpose, right? If so, what's the recommended way of running tests from the REPL then? Just invoke shadow.test.node/main like the :node-test runner does?

thheller07:03:52

npx shadow-cljs node-repl

thheller07:03:55

cljs.user=> (require 'cljs.test)
nil
cljs.user=> (require 'test.js-interop-test)
nil
> (cljs.test/run-tests 'test.js-interop-test)

Testing test.js-interop-test

Ran 2 tests containing 9 assertions.
0 failures, 0 errors.
nil
cljs.user=>

dergutemoritz07:03:13

Hmm right, the only drawback being that it can't focus on just a single test. I know I can invoke test vars directly for this (unless fixtures are involved which isn't the case here), but that rids me of the nice test summary 😢 But oh well, never mind, good enough. Thanks

thheller07:03:35

everything is possible. just might require writing the function to do what you want. nothing special about any of this.

dergutemoritz07:03:10

oh yes, I just looked at the implementation of shadow.test.node/main and found shadow.test/run-test-vars which does the trick but weirdly the REPL process terminates after invoking it

dergutemoritz07:03:47

wait now it doesn't happen anymore

dergutemoritz07:03:56

maybe it was borked somehow

dergutemoritz07:03:15

excellent, thanks for the encouragement 😄

thheller07:03:53

don't load shadow.test.node. shadow.test is fine but the shadow.test.node is for the test runner which will exit after running

dergutemoritz08:03:12

Ah right, I had that loaded before. Thanks for clearing up that mystery, too 🙂

mauricio.szabo02:04:32

I honestly just preload the test namespace (using the :preloads key under :devtools) and write/run my tests under the same target of my app :D

David Pham21:03:37

Dumb question, but is it possible to create modules from webpack while we use the :js-options {:js-provider :external} options?

thheller21:03:28

define "create modules from webpack". you mean code-split the dependencies? then the answer is no. :modules you can use just fine

David Pham21:03:29

Thanks a lot for the swift answer. exactly code split deps 🙂 The reason I am asking this is because the @react-pdf/render package requires some wasm code and it makes my whole nice code splitting useless since I am forced to use webpack xD

David Pham21:03:40

I guess it is what they call a trade-off decision 🙂

thheller21:03:23

I have some ideas on how to make this work but they are all theoretical and I don't have enough time currently to figure it out

thheller21:03:26

maybe someday 😛

dergutemoritz07:03:59

Thanks! What would be the recommended way of doing that? It seems like :node-test doesn't support connecting a REPL so I would have to have an equivalent :node-library build for that purpose, right? If so, what's the recommended way of running tests from the REPL then? Just invoke shadow.test.node/main like the :node-test runner does?