Fork me on GitHub
#shadow-cljs
<
2019-10-20
>
yenda11:10:18

I there a way to specificy the websocket port on the device? It looks like :http -> :port is only for the host, but on the device the ws port changes everytime and I don't know how to forward the port with adb. As a result I get an error about ws not able to connect from 192.x.x.x:3449 (desktop) to 192.x.x.x:random-port (device)

yenda11:10:31

and this https://shadow-cljs.github.io/docs/UsersGuide.html#repl-trouble-react-native doesn't seem to be the culprit because the IPs are correct

thheller11:10:14

@yenda not sure I understand the question. adb isn't involved in this. The running app will need to connect to the shadow-cljs instance. shadow-cljs is never trying to connect to anything, so there is no port to forward?

yenda11:10:15

ok sorry I guess I'm a bit confused about how the different parts of the tooling are connecting together. I get a red screen when the app starts about ws failing to connect from the device address on a random port to the port and host that is in my :http config

thheller11:10:55

the device is always going to use a random port, that is fine. the only fixed port is the shadow-cljs port

thheller11:10:23

what is the exact message? and are sure the host is reachable from the device?

thheller11:10:05

it may be on another network (eg. when using an emulator)

thheller11:10:30

shadow-cljs also sometimes gets confused and picks the wrong network adapter to use for the IP

thheller11:10:44

try shadow-cljs watch app --verbose

yenda11:10:54

I'm using real device

thheller11:10:07

it'll log which IP it is using on startup, but that should be the same as the logged error

thheller11:10:28

ok then you can easily test on the device by opening a browser and visiting the host:port

yenda11:10:55

it can't be reached

thheller11:10:23

and is it the actual shadow-cljs UI?

yenda11:10:14

on desktop I see shadow UI at http://192.168.1.169:3449

yenda11:10:22

on device site can't be reached

thheller11:10:53

right so things aren't on the same network?

yenda11:10:31

oh ok I can access it on device by not setting a host (so it uses localhost) and adb receiver tcp:3449 tcp:3449

thheller11:10:56

why not just wlan?

thheller11:10:17

this shouldn't require adb but I don't know much about android so should be fine

yenda11:10:48

well I can access the page but I still have this websocket error

yenda11:10:05

"WebSocket connect failed:failed to connect to /192.168.1.169 (port 3449) from /192.168.0.11 (port 49278) after 10000ms It was trying to connect to: <ws://192.168.1.169:3449>"

thheller11:10:16

hmm dunno. I have never needed adb for any of this. Just using the wlan in my local network

yenda11:10:56

oh I see, the phone is on WLAN but the desktop is on ethernet

thheller11:10:16

that should still be the same network? well, depends on your network setup I guess

yenda11:10:37

thanks that was the issue

yenda11:10:46

the phone was not on the same LAN I didn't know it was using it, I thought everything was done through adb

thheller11:10:05

yeah nothing in shadow-cljs assumes adb but maybe some react-native stuff does. I don't actually know.

thheller11:10:23

as far as shadow-cljs is concered it is regular network stuff

dabrazhe12:10:05

Hi all. Does project.clj need anything more than this below? I am using Idea with Cursive; dependencies are in shadow-cljs .edn

(defproject mininal-cljs "0.0.1"
  :dependencies
  [[thheller/shadow-cljs "2.7.8"]])

thheller12:10:47

@dennisa the question is unclear. do you intent to use project.clj only for Cursive purposes or do you actually intent to use :lein true?

dabrazhe13:10:04

Only for Cursive integration. If there's a better way please let me know.

thheller13:10:18

I would recommend running shadow-cljs pom and then using the generated pom.xml to create the Cursive project

thheller13:10:33

then whenever you change :dependencies you just re-run shadow-cljs pom

thheller13:10:15

Otherwise with project.clj you'll need to manually copy the :dependencies so Cursive knows about them

dabrazhe21:10:58

I'm bit confused, I was under impression that there's no need to include the dependencies in project.clj any longer, just a dummy file from the user guide. What is use case for adding them to project.clj?

thheller21:10:54

you don't need them there for shadow-cljs

thheller21:10:11

but Cursive does not read shadow-cljs.edn so it doesn't know about your dependencies

thheller21:10:35

so if you want cursive to understand your code and not complain about code it cannot find then you need to copy the dependencies

thheller21:10:48

just use pom.xml. you don't lose anything and it much easier to keep updated

dabrazhe21:10:00

ok, how can I go from pom to project.clj?

dabrazhe22:10:07

can I reference it somehow? cause copying is very tedious

thheller22:10:30

I dont understand that question

thheller22:10:40

you call shadow-cljs pom

thheller22:10:53

and use the generated pom.xml in cursive to create your project

thheller22:10:02

no project.clj at all

thheller22:10:17

new project from existing sources -> pom.xml

thheller22:10:32

if that doesn't do anything you may need to enable the maven plugin in cursive

dabrazhe20:10:45

Thanks, I tried and it seems to work. I guess it's ok to reimport the project everytime

thheller20:10:12

you don't need to reimport

thheller20:10:32

cursive will ask you to update if pom.xml changes, which you do by just calling shadow-cljs pom again

dabrazhe11:10:33

great! it seems to be importing now. not that I see much difference from the previous situation ) it was not complaining either. That's why I thought I only need to specify dependencies in the shadow edn and package json, not in project.clj

valtteri14:10:55

Hello, I was wondering if anyone here is doing something with Shadow + Serverless Framework and would like to share your experiences? I just gave it a spin and got it working quite easily. Superb docs @thheller 💯!

valtteri14:10:49

I’m still trying to figure out if I want to use :shadow or :require :js-provider with AWS Lambda. On the other hand I’d like to minimize “upload time” to lambda but on the other hand I don’t want to make the lambda to do too much work on initialization. I’m a bit tempted to just shove all my deps into the output js-file, which I guess :shadow would do?

pez14:10:22

I have a strange regression in Calva. It opens two REPL connections, one for clj and one for cljs. It starts by making an nREPL sessions clone and uses this for it’s clj session. Then it clones this session and promotes it to a cljs REPL. Not sure where the regression happens, but at least in 2.8.59->64 what happens is that the clj session also gets promoted to cljs. And with 2.8.2 this does not happen. I’ll try to bisect where the change happens now, since it seems like the right thing to do.

thheller15:10:13

@valtteri here is a bit more background on the "package everything" stuff for node https://github.com/thheller/shadow-cljs/issues/290

👍 1
thheller15:10:47

it is supported but it might be better to just use :require and post-process with ncc or similar tools

thheller15:10:21

@pez hmm I changed a bunch of nrepl stuff so totally possible that something broke. I might have a guess related to clone in that shadow-cljs already put something in the session which is then cloned and re-used

thheller15:10:46

do you send something before the actual clone?

pez15:10:15

@thheller I’ll have to analyze if I send something before I clone. Maybe I do, querying * ns* maybe. In any case, the change happens between 2.8.52 and 2.8.53. Shall I file an issue? I might not have a super clean repro


thheller15:10:30

would be super helpful to get a full trace of the messages. with shadow-cljs on the classpath you can run clj -m shadow.nrepl-debug 5000 5001

thheller15:10:39

that would open a TCP server on port 5000 which forwards to 5001

thheller15:10:54

so 5001 would be the actual nrepl server and your editor connects to 5000

thheller15:10:03

it just prints all the messages going back and forth

pez15:10:10

Very cool. Doing it!

thheller15:10:13

I think already know what is happening though

pez15:10:49

I don’t know how to get shadow-cljs on the classpath. I get

Execution error (FileNotFoundException) at clojure.main/main (main.java:40).
Could not locate shadow/nrepl_debug__init.class, shadow/nrepl_debug.clj or shadow/nrepl_debug.cljc on classpath. Please check that namespaces with dashes use underscores in the Clojure file name.

thheller15:10:53

well you need to recent version

thheller15:10:34

can't remember when I added it by it likely was after .53

pez16:10:28

I’m using latest.

thheller16:10:55

and it is not in some alias?

thheller17:10:09

you can just use shadow-cljs run shadow.nrepl-debug 5000 5001 too of course. just used clj as an example

pez18:10:05

I get this:

$ shadow-cljs run shadow.nrepl-debug 5000 59546
shadow-cljs - config: /Users/pez/Projects/calva/shadow-cljs.edn  cli version: 2.8.64  node: v12.8.1
shadow-cljs - connected to server
[:server-ready 5000 59546]
[:client-accepted #object[java.net.Socket 0x196e2f92 "Socket[addr=/127.0.0.1,port=59714,localport=5000]"]]
[:msg :client 36]
[:msg :client 23]
[:msg :client 90]
[:msg :client 72]
[:msg :client 72]
[:msg :client 87]
[:msg :client 160]
[:msg :client 72]
[:msg :client 87]
And in the tab where I start the watcher:
$ npx shadow-cljs -d cider/piggieback:0.4.1 -d cider/cider-nrepl:0.22.1 watch :calva-lib :test
shadow-cljs - config: /Users/pez/Projects/calva/shadow-cljs.edn  cli version: 2.8.64  node: v12.8.1
shadow-cljs - server version: 2.8.64 running at 
shadow-cljs - nREPL server started on port 59546
shadow-cljs - watching build :calva-lib
shadow-cljs - watching build :test
[:calva-lib] Configuring build.
[:test] Configuring build.
[:test] Compiling ...
[:calva-lib] Compiling ...
[:calva-lib] Build completed. (83 files, 2 compiled, 0 warnings, 3,14s)
========= Running Tests =======================

Testing calva.fmt.editor-test

Testing calva.js-utils

Testing calva.fmt.formatter-test

Testing calva.fmt.util-test

Ran 21 tests containing 88 assertions.
0 failures, 0 errors.
===============================================
[:test] Build completed. (78 files, 1 compiled, 0 warnings, 4,10s)
[:msg :target 115]
[:msg :target 79]
[:msg :target 133]
[:msg :target 180897]
[:msg :target 133]
[:msg :target 133]
[:msg :target 1953]
[:msg :target 88]
[:msg :target 79]
[:msg :target 180897]
[:msg :target 97]
[:msg :target 112]
[:msg :target 79]
[:msg :target 269351]
[:msg :target 133]
[:msg :target 79]

pez18:10:13

Then when evaluating something in the CLJ session: this:

[:msg :client 129]
[:msg :client 237]
And this:
[:msg :target 98]
[:msg :target 197]
[:msg :target 80]

pez19:10:10

That was before starting the app. Starting that and evaluating *ns*, I get this:

[:msg :client 129]
[:msg :client 101]
[:msg :client 130]
[:msg :client 131]
[:msg :client 104]
[:msg :client 118]
[:msg :client 132]
[:msg :client 104]
[:msg :client 240]
And this:
[:msg :target 2530]
[:msg :target 530]
[:msg :target 150]
[:msg :target 299]
[:msg :target 350]
[:msg :target 391]
[:msg :target 150]
[:msg :target 350]
[:msg :target 113]
[:msg :target 80]

pez19:10:08

Evaluating the same thing in the CLJS session, I get this:

[:msg :client 129]
[:msg :client 130]
[:msg :client 131]
[:msg :client 132]
[:msg :client 240]
And this:
[:msg :target 57121]
[:msg :target 57121]
[:msg :target 57121]
[:msg :target 57121]
[:msg :target 113]
[:msg :target 80]

pez19:10:56

Let me know if I can do something more/else.

thheller20:10:42

oh right. the output is written to target/nrepl-debug/*.log.edn

thheller20:10:22

the stdout output is just about the size of the messages that were written

pez20:10:26

I thought it might be some codes that made sense to you. 😃

thheller20:10:09

hmm why does it send so many clone requests?

thheller20:10:10

cider-nrepl sure sends a lot of stuff over the wire

pez20:10:30

The clone requests are from Calva, though. There are three, right?

thheller20:10:14

looks like it yes

pez20:10:32

So, one is to get a fresh clone to start from, then one clone for CLJ and one for CLJS.

thheller20:10:06

;; ----------------------------------------
;; -- FROM  :client
;; ----------------------------------------
{:op "eval",
 :session "8f0aa4a2-fb9e-4419-b032-45736496c675",
 :code "nil",
 :id "9"}

thheller20:10:17

why you eval'ing nil? was that for the test?

pez20:10:43

Not intentionally. Not sure what that is.

pez20:10:55

Which line?

pez20:10:32

nvm, found it.

pez20:10:44

I think that is something pretty recent. To get a message back with current namespace. (I could be wrong, haven’t checked yet.)

thheller20:10:19

wonder why it is sending ns-list so much although nothing changed

thheller20:10:30

doesn't matter regarding out problem though

thheller20:10:46

but I think I know what happens

pez20:10:22

I don’t recall what ns.list is right now.

pez20:10:25

If you see more funny stuff there, that you think Calva is initiating, let me know.

thheller20:10:37

can't find anything problematic your client is sending. other than that it may be sending too much

thheller20:10:55

but I've seen nrepl stuff being rather "chatty" before so thats not uncommon

pez20:10:02

yeah, very chatty

pez20:10:13

There is traffic on hover and stuff, that I might have been spawning off, b/c I didn’t think of avoiding that when doing the test.

thheller20:10:49

yeah. I think I just misunderstood how the nrepl middleware works

pez20:10:53

But whatever happens, visavi the problem, happens somewhere in the very start.

thheller20:10:39

so which messages it should handle that it also only gets those

thheller20:10:48

but I guess everything passes through it instead

thheller20:10:27

so I just need to filter out the clone stuff so make sure shadow re-inits the session

pez20:10:14

Makes some sense to me, even if not completely following. I have yet to sit down with nrepl and really try to grok it.

thheller21:10:42

nrepl is seriously frustrating ... I fixed your problem but now cursive breaks ...

thheller22:10:28

if you get a chance try 2.8.65. I think your issue should be fixed.

pez07:10:35

Now tried it. It is better, but not yet quite right. Now the first cljs clone is behaving, but the second one I clone from that clone is not a cljs session. In this log I did the following: 1. Connected Calva. This should: 1. Make a fresh clone, A 2. Clone the first CLJ session, B-CLJ, from A (used for backing the editors for .clj files) 3. Clone the second CLJ session, C-CLJ, from B-CLJ (used for the CLJ REPL prompt). 4. Clone the first CLJS session, D-CLJS, from B-CLJ (used for backing the editors for .cljs files) 5. Promote D-CLJS to a CLJS session. 6. Clone the second the second CLJS session, E-CLJS, from D-CLJS (used for the CLJS REPL prompt) Note that Calva does not promote E-CLJS, since it relies on it being cloned from the already promoted D-CLJS. What happens with 2.8.65 is that D-CLJS works as expected. But E-CLJS is still a CLJ session. So in the log file I continue to show this by: 1. Start the node-js app. 2. Evaluate a cljs/js thing in the editor (D-CLJS), this works as expected 3. Evaluate a clj think in the editor (D-CLJS), this also works as expected: bigdec does not exist. 4. Evaluate a cljs/js thing at the CLJS REPL prompt (E-CLJS), this does not work as expected. 5. Evaluate a clj thing at the CLJ REPL prompt (E-CLJS), this does not work as expected: bigdec exists. 6. For good measure I evaluate some clj things at the CLJ REPL prompt (B-CLJ), and they work as expected I hope I got all this right now


pez07:10:41

And the log


pez07:10:10

Didn’t want to upload as edn, trying zipped.

thheller08:10:14

hmm yeah I didn't expect that someone would clone a CLJS session

thheller08:10:31

since technically that makes no difference to not cloning it

thheller08:10:11

since bindings don't really work in an async context the cloning can't actually create a session that is truly independent of the other one

thheller08:10:32

but that should still work on the nrepl side of things. I'll think about it. Shouldn't be that hard to figure out

pez10:10:01

I think I do it that way because that is what I do with the CLJ sessions. I have never realized that it doesn’t really matter in the CLJS case. I can check for that and skip cloning for CLJS, in case it gets hairy for you to untangle it.

thheller10:10:23

maybe I'm wrong but I don't think that it will work. you can maybe try by eval'ing 1 in one session and then 2 in the cloned one

thheller10:10:33

then check *1 in the original and see what you get

thheller10:10:03

if you get the correct 1 I'd be surprised

thheller10:10:35

in shadow-cljs you wouldn't get 1 but maybe figwheel/piggieback does some magic I'm not aware of

pez10:10:14

I tested that immediately when you told me it would work like that. 😎 Mind blown.

thheller10:10:51

and did it work like that? 😛

pez10:10:38

Yeah. Also in figwheel it works like that.

thheller10:10:00

good to know

thheller10:10:30

but yeah sessions aren't really possible in CLJS given the async nature (and lack of proper binding support)

pez10:10:32

Naturally, I’d like to keep as much of the semantics of cloning as I can, but this could be dealt with client side now that I have been enlightened. Just let me know what you decide to do with the issue, and I’ll adapt.

thheller10:10:57

well clone should in effect to absolutely nothing

pez10:10:17

Yeah, and in .65 it does something. 😃

thheller10:10:28

all state will be shared between the clones so there is really no point in cloning in the first place

thheller10:10:10

I will need to think about how to actually allow cloning without going back to the previous behavior

pez10:10:42

Fair enough. It can actually be a bit confusing in the client code if it looks like it is a separate clone, when it isn’t.

pez10:10:40

I’ll fix that. So .65 will then be OK from a Calva perspective.

thheller10:10:39

don't change too much ... I'm still in the great REPL internals overhaul ... there may be changes upcoming that'll actually make this work

pez11:10:28

Cool. Question. If I clone a new CLJ session for the second CLJS session, will that be a separate session? I’m guessing not, but as I’m not at the keyboard and can test it, you probably know without having to try 😃

erwinrooijakkers16:10:36

I created a file build.clj as per the doc (https://github.com/thheller/shadow-cljs/wiki/Custom-builds):

(ns build
  (:require [shadow.build :as build]
            [shadow.build.targets.browser :as browser]))

(defn custom [{::build/keys [stage mode config] :as state}]
  (let [state (browser/process state)]
    (println "hello" stage)
    state))
I placed it in src/clj since that is in the :source-paths. My shadow-cljs.edn prod build is as follows:
{:lein   true
 :nrepl {:port 8777}
 :builds {:prod {:target :browser
                 :output-dir "resources/public/js/compiled"
                 :asset-path "/js/compiled"
                 :modules {:app {:entries [zenroom-example.core]}}}}}
When I do shadow-cljs release prod this custom build step is not called. How do I include the custom build step?

thheller16:10:37

:target controls that? so :target build/custom

thheller16:10:16

you might want to check out :build-hooks. they are way easier than custom builds

erwinrooijakkers16:10:10

I only want to extend the normal browser build to change one file a bit

erwinrooijakkers16:10:38

build-hooks seem perfect for that

David Pham21:10:34

Did anyone manage to make Dirac work with shadow-cljs?

thheller21:10:15

no. dirac uses the cljs.analyzer API directly, meaning shadow-cljs isn't even in the picture for the stuff it is doing

David Pham21:10:02

Ouch. Is there a way to use the repl while Chrome Devtool is on a breakpoint?

thheller21:10:58

not that I can think of no