Fork me on GitHub
#shadow-cljs
<
2020-04-27
>
joshkh11:04:00

i'm on the latest version of shadow-cljs (2.8.104) and just recently started getting a compilation error in my CI for a project that really hasn't changed:

shadow-cljs - dependencies updated
[2020-04-27 12:10:51.037 - WARNING] :shadow.build.classpath/bad-jar-contents - {:jar-file "/Users/myuser/.m2/repository/cljs-bean/cljs-bean/1.5.0/cljs-bean-1.5.0.jar", :bad-prefix "cljs_bean/from/", :bad-count 1}
shadow-cljs - HTTP server available at 
shadow-cljs - server version: 2.8.104 running at 
shadow-cljs - nREPL server started on port 9999
shadow-cljs - watching build :app
[:app] Configuring build.
[:app] Compiling ...
[:app] Build failure:
The required namespace "cljs-bean.from.cljs.core" is not available, it was required by "cljs_bean/core.cljs".
after clearing my project's .shadow-cljs dir, i started getting the same error locally. when i unzip the cljs-bean-1.5.0.jar in my m2 folder, i can see the namespace is there:
system:cljs myuser$ pwd
/Users/myuser/.m2/repository/cljs-bean/cljs-bean/1.5.0/unzipped/cljs_bean/from/cljs
system:cljs myuser$ ls
core.cljs
any thoughts are much appreciated!

thheller11:04:08

haha oops. I added a protection against jars containing compiled and uncompiled cljs sources by looking for /cljs/core.cljs

thheller11:04:21

didn't expect anyone to have that as a legit namespace

joshkh11:04:31

is there a compilation flag that i can use to ignore the check?

thheller11:04:54

@joshkh should be fine in 2.8.105

joshkh11:04:57

that did the trick! thanks @thheller for the super quick turnaround.

davewo16:04:08

upgrading from 2.8.88 to 2.8.106 to try out the build caching change... and I get this:

shadow-cljs server
shadow-cljs - config: /home/dave/projects/owsy/gondola-client/shadow-cljs.edn
shadow-cljs - starting via "clojure"
Syntax error (NoSuchFieldError) compiling at (shadow/cljs/devtools/api.clj:1:1).
ES3

Full report at:
/tmp/clojure-6373547123142623863.edn

thheller16:04:48

@davewo looks like a dependency conflict. need to bump your CLJS version as well if you have it decalred in deps.edn

davewo16:04:28

ah, lovely that fixed it, thanks!

thheller17:04:51

@yenda I did some groundwork to get that working yes but I don't know any of the react parts to actually get it to lazy load

thheller17:04:06

requires some weird messing with config files I've never seen 😛

yenda17:04:43

for us it was working with js/require

thheller17:04:16

for the build part you would set :chunks {:foo {:entries [some.ns]}} in addition to the usual stuff

thheller17:04:26

that would create a foo.js in the output-dir

thheller17:04:44

and you just load it via (js/require "./foo.js") in your code

thheller17:04:15

eh sorry :chunks {:foo some.ns/foo}

thheller17:04:38

so if you do (js/require "./foo.js") in your code you get some.ns/foo

thheller17:04:41

sorry I don't quite remember all the details for this

thheller17:04:10

been a while since I did that and I never quite figured out the react-native parts so that it would actually lazy-load that code

thheller17:04:19

and not just inline it directly like it does for normal requires

thheller17:04:28

:chunks is the new name the closure stuff uses, moving away from :modules so I just called in chunks to start

thheller17:04:50

but its not the regular :modules from a browser build. works slightly differently so that react-native can do its thing properly

yenda17:04:50

afaik inline requires are lazy-loaded

yenda17:04:56

so you don't have to do anything

thheller17:04:30

last time I tied I added a (js/console.log "I'm loaded!") the the ns that was supposed to be loaded when I click a button

thheller17:04:38

but it was always loaded directly on startup

yenda17:04:51

the key is to make sure the clojurescript code doesn't call the inline require at startup, ie in a def for instance that wouldn't work

thheller17:04:54

but its been a while so no clue

yenda17:04:59

but a memoized defn would do

thheller17:04:57

the chunking stuff should works for the basics, can easily expand it to allow more complicated configs

thheller17:04:12

but even the basics didn't work when I tried so I gave up

thheller17:04:29

the files looked like they were supposed to just metro loaded everything eagerly

yenda17:04:42

yeah we only need super basic stuff: translation files and some big js files that don't need to be loaded at startup

yenda17:04:33

I'll double check but I'm pretty sure it's just about wrapping the js/require in a defn so that it's only required when needed and not when app starts

thheller17:04:12

it might only work for release builds but in theory I set it up in a way that might also work for watch, probably not though. never could get it to lazy-load in any scenario

yenda17:04:22

might be the case yeah, though it's fine if it doesn't lazy load for watch

yenda17:04:13

ok for watch target you are right it does load when app starts

yenda17:04:31

(quoting the shadow example but it's the same in our app)

thheller17:04:09

yeah I don't do react-native myself. I never went beyond a couple hello worlds so no clue what any of it means 😛

yenda17:04:30

you can completely ignore everything about ram bundle it's useless

yenda17:04:37

it's for android only, and they made a new js engine called Hermes which AOT compiles the code. it's much better to use Hermes than ram bundles now

thheller17:04:15

ah ok. I don't follow RN much so no clue whats happening

yenda17:04:42

still loading early but it might just be dev, will have to wait a bit to test in release as I haven't fixed the android release build yet and ios is useless when it comes to logs

thheller17:04:00

let me know how it works out. curious to see if it does 🙂

yenda18:04:26

actually I changed the metro config in the wrong project

yenda18:04:32

so it still need to be tested out 😄

Spaceman19:04:25

Hi, I constantly get this mongodb driver message in my shadow-repl, and I want to turn it off:

Spaceman19:04:25

2020-04-27 15:43:14,333 [cluster-ClusterId{value='5ea55fa97eda171d0065e0f9', description='null'}- DEBUG org.mongodb.driver.cluster - Updating cluster description to  {type=REPLICA_SET, servers=[{address=, type=REPLICA_SET_SECONDARY, TagSet{[Tag{name='nodeType', value='ELECTABLE'}, Tag{name='provider', value='AWS'}, Tag{name='region', value='US_EAST_1'}]}, roundTripTime=22.6 ms, state=CONNECTED}, {address=, type=REPLICA_SET_SECONDARY, TagSet{[Tag{name='nodeType', value='ELECTABLE'}, Tag{name='provider', value='AWS'}, Tag{name='region', value='US_EAST_1'}]}, roundTripTime=20.2 ms, state=CONNECTED}, {address=, type=REPLICA_SET_PRIMARY, TagSet{[Tag{name='nodeType', value='ELECTABLE'}, Tag{name='provider', value='AWS'}, Tag{name='region', value='US_EAST_1'}]}, roundTripTime=22.4 ms, state=CONNECTED}] 
2020-04-27 15:43:14,333 [cluster-ClusterId{value='5ea55fa97eda171d0065e0f9', description='null'}- DEBUG org.mongodb.driver.cluster - Updating cluster description to  {type=REPLICA_SET, servers=[{address=, type=REPLICA_SET_SECONDARY, TagSet{[Tag{name='nodeType', value='ELECTABLE'}, Tag{name='provider', value='AWS'}, Tag{name='region', value='US_EAST_1'}]}, roundTripTime=22.6 ms, state=CONNECTED}, {address=, type=REPLICA_SET_SECONDARY, TagSet{[Tag{name='nodeType', value='ELECTABLE'}, Tag{name='provider', value='AWS'}, Tag{name='region', value='US_EAST_1'}]}, roundTripTime=20.2 ms, state=CONNECTED}, {address=, type=REPLICA_SET_PRIMARY, TagSet{[Tag{name='nodeType', value='ELECTABLE'}, Tag{name='provider', value='AWS'}, Tag{name='region', value='US_EAST_1'}]}, roundTripTime=22.7 ms, state=CONNECTED}] 
2020-04-27 15:43:14,932 [XNIO-1 I/O-13] DEBUG io.undertow.websockets.core.request - UT025003: Decoding WebSocket Frame with opCode 1 
2020-04-27 15:43:22,145 [cluster-ClusterId{value='5ea55fa97eda171d0065e0f9', description='null'}- DEBUG org.mongodb.driver.cluster - Checking status of  
2020-04-27 15:43:22,145 [cluster-ClusterId{value='5ea55fa97eda171d0065e0f9', description='null'}- DEBUG org.mongodb.driver.protocol.command - Sending command '{"ismaster": 1, "$db": "admin", "$clusterTime": {"clusterTime": {"$timestamp": {"t": 1588016580, "i": 2}}, "signature": {"hash": {"$binary": {"base64": "w/czHSxejSRK/C/k02tdLQnaRxk=", "subType": "00"}}, "keyId": 6777715635859226627}}}' with request id 25260 to database admin on connection [connectionId{localValue:100, serverValue:103115}] to server  
2020-04-27 15:43:22,161 [cluster-ClusterId{value='5ea55fa97eda171d0065e0f9', description='null'}- DEBUG org.mongodb.driver.protocol.command - Execution of command with request id 25260 completed successfully in 16.51 ms on connection [connectionId{localValue:100, serverValue:103115}] to server  
2020-04-27 15:43:22,162 [cluster-ClusterId{value='5ea55fa97eda171d0065e0f9', description='null'}- DEBUG org.mongodb.driver.cluster - Updating cluster description to  {type=REPLICA_SET, servers=[{address=, type=REPLICA_SET_SECONDARY, TagSet{[Tag{name='nodeType', value='ELECTABLE'}, Tag{name='provider', value='AWS'}, Tag{name='region', value='US_EAST_1'}]}, roundTripTime=22.6 ms, state=CONNECTED}, {address=, type=REPLICA_SET_SECONDARY, TagSet{[Tag{name='nodeType', value='ELECTABLE'}, Tag{name='provider', value='AWS'}, Tag{name='region', value='US_EAST_1'}]}, roundTripTime=19.6 ms, state=CONNECTED}, {address=, type=REPLICA_SET_PRIMARY, TagSet{[Tag{name='nodeType', value='ELECTABLE'}, Tag{name='provider', value='AWS'}, Tag{name='region', value='US_EAST_1'}]}, roundTripTime=22.7 ms, state=CONNECTED}] 
2020-04-27 15:43:24,338 [cluster-ClusterId{value='5ea55fa97eda171d0065e0f9', description='null'}- DEBUG org.mongodb.driver.cluster - Checking status of  
2020-04-27 15:43:24,338 [cluster-ClusterId{value='5ea55fa97eda171d0065e0f9', description='null'}- DEBUG org.mongodb.driver.cluster - Checking status of  
2020-04-27 15:43:24,339 [cluster-ClusterId{value='5ea55fa97eda171d0065e0f9', description='null'}- DEBUG org.mongodb.driver.protocol.command - Sending command '{"ismaster": 1, "$db": "admin", "$clusterTime": {"clusterTime": {"$timestamp": {"t": 1588016595, "i": 1}}, "signature": {"hash": {"$binary": {"base64": "rOVQeuBwIEgQnmmAJs4ylRWzPtA=", "subType": "00"}}, "keyId": 6777715635859226627}}}' with request id 25261 to database admin on connection [connectionId{localValue:101, serverValue:107380}] to server  
2020-04-27 15:43:24,339 [cluster-ClusterId{value='5ea55fa97eda171d0065e0f9', description='null'}- DEBUG org.mongodb.driver.protocol.command - Sending command '{"ismaster": 1, "$db": "admin", "$clusterTime": {"clusterTime": {"$timestamp": {"t": 1588016595, "i": 1}}, "signature": {"hash": {"$binary": {"base64": "rOVQeuBwIEgQnmmAJs4ylRWzPtA=", "subType": "00"}}, "keyId": 6777715635859226627}}}' with request id 25262 to database admin on connection [connectionId{localValue:102, serverValue:132898}] to server  
2020-04-27 15:43:24,363 [cluster-ClusterId{value='5ea55fa97eda171d0065e0f9', description='null'}- DEBUG org.mongodb.driver.protocol.command - Execution of command with request id 25261 completed successfully in 23.75 ms on connection [connectionId{localValue:101, serverValue:107380}] to server  
2020-04-27 15:43:24,363 [cluster-ClusterId{value='5ea55fa97eda171d0065e0f9', description='null'}- DEBUG org.mongodb.driver.cluster - Updating cluster description to  {type=REPLICA_SET, servers=[{address=, type=REPLICA_SET_SECONDARY, TagSet{[Tag{name='nodeType', value='ELECTABLE'}, Tag{name='provider', value='AWS'}, Tag{name='region', value='US_EAST_1'}]}, roundTripTime=22.8 ms, state=CONNECTED}, {address=, type=REPLICA_SET_SECONDARY, TagSet{[Tag{name='nodeType', value='ELECTABLE'}, Tag{name='provider', value='AWS'}, Tag{name='region', value='US_EAST_1'}]}, roundTripTime=19.6 ms, state=CONNECTED}, {address=, type=REPLICA_SET_PRIMARY, TagSet{[Tag{name='nodeType', value='ELECTABLE'}, Tag{name='provider', value='AWS'}, Tag{name='region', value='US_EAST_1'}]}, roundTripTime=22.7 ms, state=CONNECTED}] 
2020-04-27 15:43:24,363 [cluster-ClusterId{value='5ea55fa97eda171d0065e0f9', description='null'}- DEBUG org.mongodb.driver.protocol.command - Execution of command with request id 25262 completed successfully in 23.93 ms on connection [connectionId{localValue:102, serverValue:132898}] to server  
2020-04-27 15:43:24,364 [cluster-ClusterId{value='5ea55fa97eda171d0065e0f9', description='null'}- DEBUG org.mongodb.driver.cluster - Updating cluster description to  {type=REPLICA_SET, servers=[{address=, type=REPLICA_SET_SECONDARY, TagSet{[Tag{name='nodeType', value='ELECTABLE'}, Tag{name='provider', value='AWS'}, Tag{name='region', value='US_EAST_1'}]}, roundTripTime=22.8 ms, state=CONNECTED}, {address=, type=REPLICA_SET_SECONDARY, TagSet{[Tag{name='nodeType', value='ELECTABLE'}, Tag{name='provider', value='AWS'}, Tag{name='region', value='US_EAST_1'}]}, roundTripTime=19.6 ms, state=CONNECTED}, {address=, type=REPLICA_SET_PRIMARY, TagSet{[Tag{name='nodeType', value='ELECTABLE'}, Tag{name='provider', value='AWS'}, Tag{name='region', value='US_EAST_1'}]}, roundTripTime=23.0 ms, state=CONNECTED}] 

Spaceman19:04:57

Another thing I don't understand is that the mongodb connection is in the back-end, so why would it show in the shadow repl?

Spaceman19:04:12

I want to silence this logging information because it isn't helpful to me and detracts me from a good interactive experience in the repl. These messages appear periodically and move the position of the cursor and also the location of the prompt.

dvingo19:04:47

I have a simple .cljc file with the contents:

(ns my-proj.data
  (:require #?(:clj [com.wsscode.pathom.connect :as pc]))
  #?(:clj ::pc/hi)
the shadow cljs build is failing with:
Invalid keyword: ::pc/hi.
Is there something obvious I'm missing here?

thheller20:04:03

@danvingo the code is not readable in CLJS since it doesn't have the alias to resolve ::pc/hi

thheller20:04:01

I know its weird but its a quick of auto-resolved keywords, happens in CLJ too

dvingo20:04:28

ah ok cool, just wanted to make sure I wasn't going insane (at least due to this)

thheller20:04:10

@pshar10 I guess you are running shadow-cljs embedded in lein or something? no clue why you'd be getting mongodb messages, it is shadow-cljs doing that

thheller20:04:03

you if you run shadow-cljs as I recommend and not embedded in something else then you won't have this issue

thheller20:04:15

if you do something else you have to sort it out on your own

thheller20:04:47

I can give pointers maybe if you share you setup

Spaceman20:04:15

Yeah, I understand. Anyway, I added this in my project.clj, [org.slf4j/slf4j-nop "1.7.12"] which is the proposed solution, but it didn't work. My setup is basically the Luminus template.

Spaceman20:04:35

To replicate, you would make a Luminus app and then connect with a mongodb server in clj. The shadow-repl would still show the connection messages

thheller20:04:43

is there a logback.xml in the project?

thheller20:04:43

or maybe a log4j.xml?

Spaceman20:04:00

Yeah logback.xml is there. What about it?

thheller20:04:18

thats the file that controls the logging

thheller20:04:32

whats in it?

Spaceman20:04:44

<?xml version="1.0" encoding="UTF-8"?> <configuration scan="true" scanPeriod="10 seconds"> <statusListener class="ch.qos.logback.core.status.NopStatusListener" /> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <!-- encoders are assigned the type ch.qos.logback.classic.encoder.PatternLayoutEncoder by default --> <encoder> <charset>UTF-8</charset> <pattern>%date{ISO8601} [%thread] %-5level %logger{36} - %msg %n</pattern> </encoder> </appender> <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>log/vendo.log</file> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>log/vendo.%d{yyyy-MM-dd}.%i.log</fileNamePattern> <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> <maxFileSize>100MB</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy> <!-- keep 30 days of history --> <maxHistory>30</maxHistory> </rollingPolicy> <encoder> <charset>UTF-8</charset> <pattern>%date{ISO8601} [%thread] %-5level %logger{36} - %msg %n</pattern> </encoder> </appender> <logger name="org.apache.http" level="warn" /> <logger name="org.xnio.nio" level="warn" /> <logger name="io.netty" level="warn" /> <root level="DEBUG"> <appender-ref ref="STDOUT" /> <appender-ref ref="FILE" /> </root> </configuration>

thheller20:04:05

see this line <logger name="io.netty" level="warn" />

thheller20:04:22

just add <logger name="org.mongodb" level="warn" /> after it

thheller20:04:58

or change <root level="DEBUG"> to <root level="INFO">

thheller20:04:20

this has absolutely nothing to do with shadow-cljs though. this is luminus.

thheller20:04:34

but it'll make the messages disappear

thheller20:04:52

likely need to restart though

Spaceman20:04:09

Thanks that worked @thheller

👍 4
Spaceman20:04:45

A little side-question. There's this cider-test.el file for clj test support within cider. It would be good if there were an analogous one for running shadow cljs tests too. Do you have any idea what modifications would be needed in this file for that to be possible?

thheller20:04:53

I know nothing about cider sorry

Mario C.23:04:17

@pshar10

(:import org.slf4j.LoggerFactory
           ch.qos.logback.classic.Level))

(defonce server (atom nil))

(def mongo-logger (LoggerFactory/getLogger "org.mongodb.driver"))
(def jetty-logger (LoggerFactory/getLogger "org.eclipse.jetty"))

(defn log-level
  [level]
  (let [levels {:error Level/ERROR}
        l (get levels level Level/DEBUG)]
    (.setLevel mongo-logger l)
    (.setLevel jetty-logger l)))
This what I got for controlling log-level

Mario C.23:04:34

Then you just call it like this (log-level :error)

Mario C.23:04:46

This will get rid of all those mumbo jumbo, hope that helps!

dvingo20:04:27

any recommendation on how to use auto-resolved kewwords then?

dvingo20:04:37

or should i just use 2 files (cljs clj)

thheller20:04:44

just need to make sure the alias exists for cljs too

thheller20:04:12

(ns my-proj.data
  (:require #?(:clj [com.wsscode.pathom.connect :as pc]
               :cljs [clojure.string :as pc]))

thheller20:04:28

doesn't really matter what it resolves to if you are not going to use in it CLJS anyways

dvingo20:04:38

ok got it. thanks

Spaceman21:04:50

Is there a way to define a custom function in the shadow.repl namespace, because I want to automatically run shadow/watch for a couple of profiles?

aisamu21:04:47

You can invoke arbitrary functions from shadow's cli (and those can start the build with your requirements) https://shadow-cljs.github.io/docs/UsersGuide.html#clj-run

Spaceman04:04:13

@U1UQEM078 my cider automatically runs this command:

/usr/local/bin/npx shadow-cljs -d nrepl:0.6.0 -d refactor-nrepl:2.5.0-SNAPSHOT -d cider/cider-nrepl:0.23.0 server
Given this, where do I put the functions I need to run on the repl startup?

aisamu14:04:04

You can configure the command cider uses to start the repl - https://docs.cider.mx/cider/cljs/shadow-cljs.html#_configuration Those vars go in a .dir-locals.el file:

((clojure-mode
  (cider-preferred-build-tool . "clojure-cli")
  (cider-clojure-cli-global-options . "-A:dev"))

Spaceman19:04:54

So exactly I want this: 1. I start a shadow repl using M-x return ' and choose shadow 2. Then shadow.user> repl prompt is shown. 3. In this I always evaluate this: (do (shadow/watch :app) (shadow/watch :workspaces) (shadow/repl :workspaces)) 4. In order to run these functions automatically, what do I need to do exactly?

aisamu19:04:58

This might be a better question for #cider. I recall there being a custom command to start clojurescript REPLs...

Spaceman22:04:48

@thheller is there a way to integrate shadow-cljs with kaocha-cljs yet?

Spaceman23:04:00

I'm trying to run the kaocha-cljs library, and I've installed it by adding kaocha and kaocha depencies in my project.clj

Spaceman23:04:58

But when I evaluate a kaocha test in the clj repl, I get the following error:

(run 'vendo.workspaces.cards_test) ;; cljs file


Caused by: clojure.lang.ExceptionInfo: No such namespace: @testing-library/react, could not locate _CIRCA_testing_library_SLASH_react.cljs, _CIRCA_testing_library_SLASH_react.cljc, or JavaScript source providing "@testing-library/react" (Please check that namespaces with dashes use underscores in the ClojureScript file name) in file /Users...
I installed this library through npm and it's in that cards_test namespace. How do I run kaocha tests then that include npm dependencies?