shadow-cljs

https://github.com/thheller/shadow-cljs | https://github.com/sponsors/thheller | https://www.patreon.com/thheller
Luis Santos 2021-02-07T14:44:56.013500Z

Hi everyone, Whats the recommended way to use static assets installed via npm? Let's say that I want to install bootstrap or tailwindcss using CSS and I want the assets to be available int he public folder and later in the dist folder. What are the best practices?

Luis Santos 2021-02-07T14:44:57.013700Z

Thanks

thheller 2021-02-07T15:31:06.014200Z

I just use tailwind with postcss as described in the tailwind docs

👍 1
aratare 2021-02-07T15:54:12.016500Z

Hi there. I'm combing through the doc and there doesn't seem to be any way to tell shadow-clj which lein profile to use dynamically instead of having it hardcoded inside shadow-cljs.edn? The reason for this is I have multiple lein profiles, each of which corresponding to different environment like dev, test, prod, etc. and I'd like shadow-clj to be able to do the same. Would appreciate any insight. Thanks in advance 🙂

thheller 2021-02-07T16:46:04.017600Z

shadow-cljs does not support this and it usually isn't required for CLJS. at least I haven't heard a convincing argument for it yet 😉

thheller 2021-02-07T16:46:27.017800Z

you can just use lein if you really must

thheller 2021-02-07T16:46:47.018300Z

instead of shadow-cljs release app you do lein with-profiles +whatever run -m shadow.cljs.devtools.cli release app

aratare 2021-02-07T18:00:17.020600Z

Thanks a lot 🙂 I'm not sure if it's technically hard to do but having separate lein config inside each build would be nice for something like this I imagine.

coby 2021-02-07T20:20:09.031100Z

I'm having an adventure failing to understand how to connect my editor (Neovim/Conjure) to a REPL for a :target :node-script build. So first I'm doing shadow-cljs start && shadow-cljs clj-repl app and then running (shadow/watch :app) and (shadow/repl :app) from there, per https://shadow-cljs.github.io/docs/UsersGuide.html#_nrepl_usage. The prompt then changes to cljs.user=> and when I evaluate forms directly from there it complains "No application has connected..." which is to be expected I think since I haven't actually started a Node process. So far so good I guess. However, at this point when I do :ConjureConnect 7001 from my editor and try to evaluate forms, it is connecting to a plain Clojure REPL and doesn't consider JS forms e.g. (js/console.log ...) valid. I think this is because the (shadow/... :app) forms only transform that one client connection into a CLJS REPL; the nREPL server itself is still in Clojure "mode"...but how do I get the server itself to compile CLJS forms?

thheller 2021-02-07T20:49:17.032Z

@ctamayo first of all are you sure shadow-cljs node-repl isn't enough for your use case? second if you connect to the nrepl that connection starts out in CLJ mode. so you switch it via (shadow/repl :app)

thheller 2021-02-07T20:49:52.032600Z

the server is always in CLJ mode and that cannot be changed. you just switch your connection when needed.

1
thheller 2021-02-07T20:54:53.033500Z

the way things currently work this is not possible and I have no interest in changing it. if you must do this you can just use lein as described.

coby 2021-02-07T20:58:49.035800Z

When I do shadow-cljs node-repl it starts up the server on 7001 but when I do :ConjureConnect 7001 it complains:

[2021-02-07 12:53:39.022 - WARNING] :shadow.cljs.devtools.server.nrepl-impl/init-ns-ex - {:init-ns <http://media-server.app|media-server.app>}
FileNotFoundException Could not locate media_server/app__init.class, media_server/app.clj or media_server/app.cljc on classpath. Please check that namespaces with dashes use underscores in the Clojure file name.
My main file is src/media_server/app.cljs and when I change it to .clj it complains that the ns form does not conform to spec because I'm trying to require the "fs" node module.

thheller 2021-02-07T21:00:23.036700Z

sorry I can't answer conjure questions. I have never used it and have no idea what it does.

thheller 2021-02-07T21:01:50.037400Z

looks like its trying to change the CLJ connection to that ns. that will not work, it needs to be switched to CLJS first

coby 2021-02-07T21:02:33.038100Z

It's a REPL client for Neovim, no worries :thumbsup::skin-tone-3:

thheller 2021-02-07T21:02:35.038400Z

think of shadow-cljs as a CLJ server only. it then takes commands to build CLJS. you cannot eval CLJS without giving those commands first

thheller 2021-02-07T21:03:09.038900Z

I know what it is. I just don't know what it does on connect and stuff

thheller 2021-02-07T21:04:30.040500Z

for the node-repl you can just run shadow-cljs server .. connect to nrepl and then run (shadow/node-repl)

coby 2021-02-07T21:04:46.041100Z

Yeah, I immediately remembered I hadn't done that, sorry. Here's what happens when I do though.

$ shadow-cljs node-repl
shadow-cljs - config: /home/tamayo/projects/media-player/server/shadow-cljs.edn
shadow-cljs - server version: 2.9.6 running at <http://localhost:9630>
shadow-cljs - nREPL server started on port 7001
cljs.user=&gt; (shadow/watch :app) ;; &lt;----------- TRYING TO SWITCH MODES HERE ----------&lt;&lt;&lt;&lt;&lt;
------ WARNING - :undeclared-ns ------------------------------------------------
 Resource: :1:2
 No such namespace: shadow, could not locate shadow.cljs, shadow.cljc, or JavaScript source providing "shadow"
--------------------------------------------------------------------------------
------ WARNING - :undeclared-var -----------------------------------------------
 Resource: :1:2
 Use of undeclared Var shadow/watch
--------------------------------------------------------------------------------
TypeError: shadow.watch is not a function
    at cljsEval (&lt;eval&gt;:1:16)
    at global.SHADOW_NODE_EVAL ([stdin]:105:10)
    at Object.shadow$cljs$devtools$client$node$node_eval [as node_eval] (/home/tamayo/projects/media-player/server/.shadow-cljs/builds/node-repl/dev/out/cljs-runtime/shadow/cljs/devtools/client/node.cljs:24:1)
    at ret (/home/tamayo/projects/media-player/server/.shadow-cljs/builds/node-repl/dev/out/cljs-runtime/shadow/cljs/devtools/client/node.cljs:49:13)
    at Object.shadow$cljs$devtools$client$env$repl_call [as repl_call] (/home/tamayo/projects/media-player/server/.shadow-cljs/builds/node-repl/dev/out/cljs-runtime/shadow/cljs/devtools/client/env.cljs:120:11)
    at Object.shadow$cljs$devtools$client$node$repl_invoke [as repl_invoke] (/home/tamayo/projects/media-player/server/.shadow-cljs/builds/node-repl/dev/out/cljs-runtime/shadow/cljs/devtools/client/node.cljs:47:1)
    at shadow$cljs$devtools$client$node$process_message (/home/tamayo/projects/media-player/server/.shadow-cljs/builds/node-repl/dev/out/cljs-runtime/shadow/cljs/devtools/client/node.cljs:106:5)
    at /home/tamayo/projects/media-player/server/.shadow-cljs/builds/node-repl/dev/out/cljs-runtime/shadow/cljs/devtools/client/env.cljs:242:9
    at Object.shadow$cljs$devtools$client$env$process_next_BANG_ [as process_next_BANG_] (/home/tamayo/projects/media-player/server/.shadow-cljs/builds/node-repl/dev/out/cljs-runtime/shadow/cljs/devtools/client/env.cljs:194:7)
    at Object.shadow$cljs$devtools$client$env$process_ws_msg [as process_ws_msg] (/home/tamayo/projects/media-player/server/.shadow-cljs/builds/node-repl/dev/out/cljs-runtime/shadow/cljs/devtools/client/env.cljs:248:7)
cljs.user=&gt;

thheller 2021-02-07T21:04:47.041200Z

or shadow-cljs server ... connect nrepl then (shadow/watch :app) and (shadow/repl :app)

thheller 2021-02-07T21:05:22.042100Z

if you run shadow-cljs node-repl in the command line that will drop you directly into CLJS mode as indicated by cljs.user=&gt; prompt

thheller 2021-02-07T21:05:31.042500Z

but ONLY that command. not the nrepl server

coby 2021-02-07T21:05:53.042900Z

only that command meaning only that connection/client?

thheller 2021-02-07T21:06:19.043500Z

listen. kill all processes. run shadow-cljs server.

thheller 2021-02-07T21:06:33.043900Z

that starts a blank server that just does nothing except wait for further commands

thheller 2021-02-07T21:06:47.044200Z

THEN connect nrepl or run other commands in a separate terminal

thheller 2021-02-07T21:07:43.044900Z

you can use the shadow-cljs commands or you can run all those directly over nrepl

thheller 2021-02-07T21:07:52.045200Z

just don't confuse the two and their purpose

thheller 2021-02-07T21:11:39.047500Z

sorry for making this more confusing by bringing up node-repl. that is just a simplified node repl that is already ready to go with its own node process but not coupled to any build

thheller 2021-02-07T21:11:56.048Z

vs :node-script where you have to manage the node process yourself

coby 2021-02-07T21:16:58.050600Z

> not coupled to any build I see, that is the piece I was missing. I understand the piece about server vs the various REPL commands...I tried various ways but still can't get my editor REPL to play nice with CLJS. So I need to just figure out what the issue is on the Conjure side. Sorry if it seemed like I wasn't listening, I was just trying to validate my understanding.

thheller 2021-02-07T21:17:38.051Z

so you get an error if you run shadow-cljs server and then connect conjure? without doing anything else?

thheller 2021-02-07T21:18:37.051600Z

that shouldn't happen but if it does its on the conjure side of things

thheller 2021-02-07T21:18:51.051900Z

unless you maybe configure :nrepl {:init-ns ...} in your shadow-cljs.edn config?

coby 2021-02-07T21:19:32.052400Z

Ah, I did do that, now I understand why it wouldn't like that...

coby 2021-02-07T21:20:23.053Z

and yes, it errors at that point w/o anything else

thheller 2021-02-07T21:20:48.053600Z

right yeah. that would switch the CLJ nrepl to that ns but since its a CLJS ns that doesn't work

thheller 2021-02-07T21:21:06.054200Z

you switch the default ns for you build via :devtools {:repl-init-ns foo.bar} in your build config instead

coby 2021-02-07T21:21:25.054500Z

gotcha, that makes sense

genekim 2021-02-07T23:00:56.057500Z

I’m using shadow-cljs on an M1 MacBook Pro for a couple of week. (PS: it’s amazing. IntelliJ/Cursive, shadow-cljs watch, kaocha watch, Fulcro RAD app running in browser. Laptop stays cool, totally silent, and runs for hours with only 20-30% battery consumed. So different than my Intel MBP, which would last for no more than 45m!) But I have noticed something strange, and don’t know how to best document this strange behavior. When using an ARM JVM (either IntelliJ JBR or Azul JVM), it seems to take much longer to detect file changes. This affects the shadow-cljs builds, and kaocha watch tests. When a save a file, it may take between 3 seconds and maybe even up to 10+ seconds for the file change to trigger a compile or test run. Has anyone else run into this problem? Is there a simple test case or scenario I can use to isolate what is causing the delay? (I haven’t tried using an x86 JVM yet. I’m sufficiently afraid I’ll permanently break my dev setup by doing that… Unwarranted I’m sure, but… 🙂

thheller 2021-02-07T23:09:18.058500Z

@genekim I assume this is on Big Sur so try the latest version. I removed the old hawk file watching lib which seemed to cause trouble on Big Sur

🤯 2
thheller 2021-02-07T23:09:45.058900Z

2.11.17

genekim 2021-02-07T23:09:56.059200Z

Incredible, @thheller. Thank you!! Always blown away by shadow-cljs , and how it makes the build system just fade into the background, in the best possible way! 🎉🎉🎉 So wonderful!

❤️ 3
thheller 2021-02-07T23:10:31.060100Z

don't know anything about how it affects M1 though. only had reports from older hardware but all related to big sur so maybe the same on M1

genekim 2021-02-07T23:11:47.060400Z

Will try this right now!

thheller 2021-02-07T23:12:43.060600Z

you can also set :fs-watch {:hawk false} in shadow-cljs.edn top level on older versions, basically the same effect

genekim 2021-02-07T23:22:58.060900Z

Confirmed that file watcher issue seems to have disappeared. Thanks, @thheller!!

👍 2