Hey. Just made my first ClojureScript Hello-World run on my Omega2+ microcontroller using https://shadow-cljs.github.io/ incl. REPL and Emacs/CIDER and nREPL. I wrote these step-by-step instructions https://gist.github.com/henrik42/08e70e8fc0d9068e1fd40debec41ffdc#file-clojurescript-on-a-microcontroller-md in German. Hope this stuff is usefull for somebody. Leave a note if you would like an English version.
@thheller I'm using :output-dir
now. And using compile
works. Then I can run:
docker run --rm -it --user node -v C:\henrik42\projekte\hello-world-app\hello-world-target\:/the-app/hello-world-target/ -w /the-app/ theasp/clojurescript-nodejs:shadow-cljs-alpine node hello-world-target/hello-world-with-server.js
So all I need is hello-world-target
But when I use watch
I get an error. It seems that the node runtime need some things below .shadow-cljs but I cannot pin point it.
Any idea?
SHADOW import error /the-app/hello-world-target/cljs-runtime/shadow.js.shim.module$ws.js
/the-app/hello-world-target/hello-world-with-server.js:67
throw e;
^
Error: Cannot find module 'ws'
Require stack:
- /the-app/hello-world-target/hello-world-with-server.js
at Function.Module._resolveFilename (internal/modules/cjs/loader.js:954:17)
at Function.Module._load (internal/modules/cjs/loader.js:847:27)
at Module.require (internal/modules/cjs/loader.js:1016:19)
at require (internal/modules/cjs/helpers.js:69:18)
at /the-app/hello-world-target/cljs-runtime/shadow.js.shim.module$ws.js:3:28
at global.SHADOW_IMPORT (/the-app/hello-world-target/hello-world-with-server.js:64:44)
at /the-app/hello-world-target/hello-world-with-server.js:2259:1
at Object.<anonymous> (/the-app/hello-world-target/hello-world-with-server.js:2266:3)
at Module._compile (internal/modules/cjs/loader.js:1121:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1160:10) {
code: 'MODULE_NOT_FOUND',
requireStack: [ '/the-app/hello-world-target/hello-world-with-server.js' ]
}
@henrikheine you still need the node_modules
folder. ws
is the npm package for websocket node, it is used for the REPL and hot-reload.
@thheller ok, thx. Any sense in trying to boil that down further? Or just rsync the complete node_modules ?
you can just run npm init -y
in the :output-dir
and then npm install ws
(plus any other packages you might need)
so it'll only have the packages you actually want for the runtime
Excellent! Thanks again.
@thheller I'm seeing a strange error. I create ./hello-world-target/, do an "npm init -y" then "npm install ws source-map-support", then start "shadow-cljs watch with-server". My Hook fires. 98 files get transfered. shadow-cljs - config: /home/node/projekte/hello-world-app/shadow-cljs.edn cli version: 2.8.76 node: v13.2.0 shadow-cljs - server version: 2.8.76 running at http://localhost:9630 shadow-cljs - nREPL server started on port 9000 shadow-cljs - watching build :with-server [:with-server] Configuring build. [:with-server] Compiling ... exec: rsync --stats --times --inplace -r hello-world-target <rsync://henrik42>@192.168.3.1:4567/henrik42/ {:exit 0, :out Number of files: 108 (reg: 98, dir: 10) Number of created files: 108 (reg: 98, dir: 10) Number of deleted files: 0 Number of regular files transferred: 98 Total file size: 2,068,862 bytes Total transferred file size: 2,068,862 bytes Literal data: 2,068,862 bytes Matched data: 0 bytes File list size: 0 File list generation time: 0.001 seconds File list transfer time: 0.000 seconds Total bytes sent: 2,075,837 Total bytes received: 1,954 sent 2,075,837 bytes received 1,954 bytes 1,385,194.00 bytes/sec total size is 2,068,862 speedup is 1.00 , :err } [:with-server] Build completed. (60 files, 1 compiled, 0 warnings, 5.18s) When I run "node hello-world-target/hello-world-with-server.js" on the micro I get an error saying hello-world-target/cljs-runtime/goog.html.safestylesheet.js is missing. And it is missing on the micro. But I can see it on my PC. Then I run manually (the compiler does not kick in before this - I'm not changing any sources). This time we have 169 files of which 71 get transfered. bash-5.0$ rsync --stats --times --inplace -r hello-world-target <rsync://henrik42>@192.168.3.1:4567/henrik42/ Number of files: 179 (reg: 169, dir: 10) Number of created files: 71 (reg: 71) Number of deleted files: 0 Number of regular files transferred: 71 Total file size: 7,024,421 bytes Total transferred file size: 4,955,559 bytes Literal data: 4,955,559 bytes Matched data: 0 bytes File list size: 0 File list generation time: 0.001 seconds File list transfer time: 0.000 seconds Total bytes sent: 4,963,455 Total bytes received: 1,382 sent 4,963,455 bytes received 1,382 bytes 1,985,934.80 bytes/sec total size is 7,024,421 speedup is 1.41 If I run the rsync again no more files get tranfered. This looks as if somes files where created/changed after the hook was fired. A concurrent race?
I did this twice - seems reproducable.
After the second rsync the "node hello-world-target/hello-world-with-server.js" runs fine.
I inserted a (Thread/sleep 3000) before the rsync - now it works on first run.
oh yes that might be a bug. hook getting called too early. you can call (shadow.build.async/wait-for-pending-tasks! build-state)
in the hook. that should wait for everything to complete
Great. Thx. Shall I open an issue?
yes please so it doesn't get lost
Will do it tomorrow.
@thheller Just one more question: in C:\henrik42\projekte\hello-world-app\hello-world-target\hello-world-with-server.js
I noticed global.CLOSURE_DEFINES = {...,"shadow.cljs.devtools.client.env.devtools_url":"http:\/\/192.168.3.142:9630"
So the URL/IP/Hostname of the watch
-server is build into the JavaScript target file. So this "client" can ever only run again this one and only server host. Can I put any Clojure form into shadow-cljs.edn/:devtools {:devtools-url
or just string literals? I'm thinking of reading some configuration that I could put different URLs into so that I can control the URL in each runtime.
watch
output is only ever meant to be used with the currently running shadow-cljs instance
if you want to distribute something use release
you can use #shadow/env
and environment variables if you need to
hey. set :output-dir
in your build config. then you don't need to transfer the .shadow-cljs
dir at all.
:output-to "foo/script.js" :output-dir "foo"
then mount foo
via sshfs and you are good to go.
and you can use watch
for hot-reload if you want
@thheller good point. I noticed that .shadow-cljs contains lots of stuff that I dont need in Node.js. Syncing just one dir tree is smart. Thx
@thheller jupp. I am using watch
How do I get better clojurescript error messages. As of right now, I'm just getting back an object with a stack string, but... I'm cant be expected to look at the stringified, line-escaped stack message everytime, right? Is theres a way to at least get it pretty printed and hide the irrelevant stack frame in the browser? I'm using shadow-cljs and leinigen and lein-shadow and running / testing in firefox
I assume you're talking about ex-info
and not about js/Error
.
It's the issue with Firefox - it doesn't support custom formatters.
The relevant FF issue: https://bugzilla.mozilla.org/show_bug.cgi?id=1262914
And it works just fine for me on Chrome with https://github.com/binaryage/cljs-devtools
Thanks!I thought to check Chrome right after I posted this and noticed it looks better, thanks for the extension! Turns out I shouldn't have been ignoring that [INFO] about custom formatters after all.