shadow-cljs

https://github.com/thheller/shadow-cljs | https://github.com/sponsors/thheller | https://www.patreon.com/thheller
Volodymyr Huzar 2021-04-19T09:13:00.315200Z

I have a problem with starting shadow-cljs server on my Jenkins Alpine Linux machine using shadow-cljs start After long time I’m getting

shadow-cljs - server starting "a lot of dots and" `Cannot contact jenkins_cluster: hudson.remoting.RequestAbortedException: java.nio.channels.ClosedChannelException` error.
It could be some policy of our Jenkins which doesn’t allow that but I cannot find any information which I can pass to our DevOps to investigate that. Is the some way to get more details what is going on under the hood of this command? Or maybe there is a way to enable some logs (`-v` and --debug shows nothing)?

Volodymyr Huzar 2021-04-21T12:07:28.375400Z

@thheller thanks for you advices, they helped me to find root cause of the problem. I will create an issue in GitHub for use case that start is hanging when error occurs during start up if you don’t mind. My root issue on Jenkins was that jks ssl certificate which we use for local environment was not committed and I still not sure is it a good idea to commit it. Is it possible somehow to force shadow-cljs to ignore ssl certificate if it is not found instead of throwing exception?

thheller 2021-04-21T12:09:43.377800Z

if the cert is not found ssl won't work? or do you not need that to work?

Volodymyr Huzar 2021-04-21T12:10:59.379300Z

I don’t need that to work. I need SSL for local server but not when I run tests

thheller 2021-04-21T12:12:22.380200Z

hmm yeah I guess there should be an option to disable that but for CI you could just write a simple script that just deletes the :ssl config from shadow-cljs.edn before actually starting it

Volodymyr Huzar 2021-04-21T12:13:59.382Z

Option will be better, but I try to write something in meanwhile

thheller 2021-04-21T12:16:20.385300Z

(require '[<http://clojure.java.io|clojure.java.io> :as io])
(require '[clojure.edn :as edn])
(let [file (io/file "shadow-cljs.edn")]
  (-&gt; (slurp file)
      (edn/read-string)
      (dissoc :ssl)
      (as-&gt; config
        (spit file (pr-str config)))))

thheller 2021-04-21T12:16:42.385500Z

if you have clojure installed on the CI system you can just put that into a script file and run it with that

thheller 2021-04-21T12:16:47.385700Z

or use something like babashka

Volodymyr Huzar 2021-04-21T12:21:03.389900Z

thanks a lot. I’ll try

thheller 2021-04-21T12:30:07.394100Z

feel free to open issues about this. can't get to it now but maybe later

ingesol 2021-04-19T10:41:50.319300Z

While setting up :js-provider :external, I have found that it only works with ["react" as react] style requires. Meaning that both the string-style and the alias is required in order for the corresponding js require to be generated. Is this a known issue/by design? This could be very tricky for others to figure out. The string syntax is fine, when documented, but the required alias is more of a pitfall.

Volodymyr Huzar 2021-04-19T10:43:44.319400Z

The same is going one when I try to run shadow-cljs start on Docker image https://github.com/theasp/docker-clojurescript-nodejs locally. You can reproduce it from your project directory using

docker run --rm -v ${PWD}:/home/my-project -w="/home/my-project" theasp/clojurescript-nodejs:latest npx shadow-cljs start

thheller 2021-04-19T14:14:22.319900Z

why are you using start in a CI environment?

thheller 2021-04-19T14:16:03.320300Z

@ingesol that is a bug yes

ingesol 2021-04-19T14:20:06.320800Z

@thheller Ok, I’ll retest to verify the pattern and post a bug

emier 2021-04-19T14:22:20.320900Z

Thanks for the reply @dannyfreeman, that seems to do what I want it to! However, now I get a problem with the modules that are required from the preloaded js file. So right now I have my preload namespace:

(ns preloads
  (:require ["./myPreloads.js"]))
and the js file I want to run, which requires its own modules myPreloads.js
...
require("module-alias/register");
...
I get the following error when trying to run the tests:
SHADOW import error /app/.shadow-cljs/builds/test/dev/out/cljs-runtime/myPreloads.js

/app/test/target/testable.js:67
    throw e;
    ^
Module not provided: shadow.js.shim.module$module_alias$register
Looking at the generated testfile testable.js, this is where it does the import.
SHADOW_IMPORT("shadow.js.shim.module$module_alias$register.js");
Can’t really figure out how to require these modules so that shadow can find them. Am I missing something here?

lispers-anonymous 2021-04-19T14:24:55.321200Z

That I am unsure about. I did run into some issues around testing code meant for a browser for a node-test target that seems similar. To fix those issues I had to set this option in my :test profile in shadow-cljs.edn file

:js-options {:entry-keys ["module" "browser" "main"]}

lispers-anonymous 2021-04-19T14:25:48.321400Z

I'm really unsure what the implications of doing that are, but combining that with stubbing out the global window object got my tests to run in node.

lispers-anonymous 2021-04-19T14:45:43.321700Z

Also, if the contents of myPreloads.js are pretty simple, you could try re-writing them in clojurescript directly in your preloads cljs file. Perhaps shadow-cljs doesn't understand the code in your js file.

emier 2021-04-19T14:48:52.321900Z

Okay, from the docs it seems like :js-options determines which build variant to use for the npm package, e.g. CommonJS or ESM. Unfortunately, adding it doesn’t do anything for me. Unfortunately, myPreloads.js is quite extensive so I’m trying to avoid rewriting it in cljs.

Volodymyr Huzar 2021-04-19T14:50:41.322100Z

@thheller I would like to use https://github.com/lambdaisland/kaocha-cljs2 to run tests and I need somehow to serve the compiled tests with shadow-cljs, so I have decided to use shadow-cljs server for that. I am not sure if it is the best choice. I would appreciate a better advice on that if you have

thheller 2021-04-19T14:52:13.322300Z

hmm I don't know anything about kaocha or how it runs tests unfortunately

thheller 2021-04-19T14:52:43.322500Z

you could maybe run the tests via https://shadow-cljs.github.io/docs/UsersGuide.html#clj-run

emier 2021-04-19T14:53:46.322800Z

@thheller any ideas on how to fix this error related to shadow-cljs being unable to import npm modules that are required from a local js-file which in turn was required in a preload namespace? More info in my first reply of this thread

emier 2021-04-19T14:55:30.323Z

Not sure if it makes a difference, but the modules it can’t find seems to be devDependencies

thheller 2021-04-19T15:02:13.323200Z

how are you running the tests? it is :node-test I presume?

Volodymyr Huzar 2021-04-19T15:03:21.323400Z

Actually what I need is to serve the complied directory with lambdaisland.chui.remote to be preloaded. And shadow-cljs server looks ideal. I could try to look for another way to achieve the same. But do you have any idea why it doesn’t work on Docker? Is it expected or can I log the issue in GitHub for that?

thheller 2021-04-19T15:07:21.323600Z

I don't have a clue why it wouldn't work. maybe the logfiles created in the .shadow-cljs/ dir provide some clues? I'm not capable of debugging docker issues. if server works fine I'd assume start to work as well since the only thing it does is detach to process into the background.

Volodymyr Huzar 2021-04-19T15:22:33.323800Z

let me actually check if shadow-cljs server works inside Docker. I haven’t checked it separately

witek 2021-04-19T15:53:59.326600Z

Hi. I am building with :target :node-library and I would like to use the fetch api. But (js/fetch ...) fails with fetch is not definded and requiring ["node-fetch"] fails with symbol module$shadow_js_shim_module$node_fetch already provided by [:shadow.build.js-support/require "node.fetch"], conflict with [:shadow.build.js-support/require "node-fetch"]. Any suggestions how to access the fetch function? Thank you.

thheller 2021-04-19T16:08:55.327Z

looks like you have a node.fetch and a node-fetch? they clash, stick to one I guess?

Volodymyr Huzar 2021-04-19T16:25:02.327100Z

@thheller when I am using shadow-cljs server with local docker I get a project specific error (out of scope for my question). But it seems shadow-cljs start hanging when errors occur, is it possible?

thheller 2021-04-19T16:28:30.327300Z

how does it fail? could certainly affect start yes

Volodymyr Huzar 2021-04-19T16:41:25.328800Z

shadow-cljs server failed (actually process just ends) during fetching lein private dependencies because of luck of permissions. During shadow-cljs start it just shows dots

witek 2021-04-19T16:42:49.329400Z

What do you mean by "you have"? In my own namespaces I don't use any of these. But I would like to and I can not fugure out how to require it.

thheller 2021-04-19T16:44:02.329700Z

you said "requiring node-fetch failed". try node.fetch

thheller 2021-04-19T16:44:31.330300Z

which shadow-cljs version do you use? I thought these kinds of clashes were fixed?

thheller 2021-04-19T16:45:05.330400Z

yeah with start all logging goes into the log files in .shadow-cljs/server.stdout.log or server.stderr.log

witek 2021-04-19T16:50:41.333200Z

I am on the latest version. Requiring [node.fetch :as nf] errors in the compiler with he required namespace "node.fetch" is not available. Requiring ["node.fetch" :as nf] passes the compiler, but errors at runtime when loading with Error: Cannot find module 'node.fetch'. 😞

thheller 2021-04-19T16:52:01.334200Z

I'm confused then. something else appears to be using it?

thheller 2021-04-19T16:52:17.334500Z

so even if you fix your end it still won't run since that uses it?

witek 2021-04-19T16:53:11.334900Z

Everything runs fine. Until I require anything of it.

thheller 2021-04-19T16:54:00.335300Z

I'm entirely confused. WHERE does the "node.fetch" come from? if you ONLY have "node-fetch" that should be totally fine but having that as well as "node.fetch" will not work

thheller 2021-04-19T16:55:11.336600Z

as the error tells you SOMETHING required "node.fetch"

witek 2021-04-19T16:55:18.336700Z

I have some dependencies. Like firebase-admin and firebase-functions. Perhaps it comes from there.

thheller 2021-04-19T16:55:36.337Z

not if you are using :node-library, then shadow-cljs will not process any npm dependencies at all. some CLJS code must be requiring that

witek 2021-04-19T16:58:06.338200Z

Ok, I will check. Or narrow down my scope. Thank you very much for your time!

thheller 2021-04-19T17:00:37.338700Z

also verify which shadow-cljs version you are using. I thought I fixed this particular issue.

thheller 2021-04-19T17:01:10.339500Z

the problem is that node-fetch AND node.fetch both munge into the module$shadow_js_shim_module$node_fetch pseudo-namespace and they need to be unique

thheller 2021-04-19T17:02:04.340200Z

although I don't understand how you get that name to be honest. that should be shadow.js.shim.module$node_fetch. might be something weird in your setup, can't say

witek 2021-04-19T17:34:56.342Z

For the record. What I forgot to mention 😞 is that my compiled code is not executed directly - instead the Firebase Cloud Functions Emulator loads it. I added "node-fetch" to my package.json and now requireing "node-fetch" works.