shadow-cljs

https://github.com/thheller/shadow-cljs | https://github.com/sponsors/thheller | https://www.patreon.com/thheller
zendevil 2021-03-11T10:06:51.321800Z

I get these two errors periodically in my react-native app:

[Thu Mar 11 2021 15:25:10.620]  WARN     The shadow-cljs Websocket was disconnected.
[Thu Mar 11 2021 15:25:10.640]  ERROR    shadow-cljs - remote-error {"isTrusted": false, "message": "The operation couldn't be completed. Operation timed out"}
[Thu Mar 11 2021 15:26:37.705]  WARN     The shadow-cljs Websocket was disconnected.
[Thu Mar 11 2021 15:26:37.706]  ERROR    shadow-cljs - remote-error {"isTrusted": false, "message": "The operation couldn't be completed. Operation timed out"}
[Thu Mar 11 2021 15:28:01.413]  WARN     The shadow-cljs Websocket was disconnected.
[Thu Mar 11 2021 15:28:01.419]  ERROR    shadow-cljs - remote-error {"isTrusted": false, "message": "The operation couldn't be completed. Network is unreachable"}
[Thu Mar 11 2021 15:29:27.332]  WARN     The shadow-cljs Websocket was disconnected.
[Thu Mar 11 2021 15:29:27.333]  ERROR    shadow-cljs - remote-error {"isTrusted": false, "message": "The operation couldn't be completed. Operation timed out"}
everything is running smoothly but I get the warning and error periodically.

thheller 2021-03-11T10:08:29.322700Z

looks like the app is losing the websocket connection to the shadow-cljs instance. maybe the device going to sleep or so?

zendevil 2021-03-11T10:49:52.323300Z

i’m running this on the simulator currently, and it has never gone to sleep

thheller 2021-03-11T10:52:39.324500Z

no clue. must be something in the emulator/app. does this ever happen when you actually using the "device" or does it just happen if its sits "idle" for 90sec?

zendevil 2021-03-11T10:53:33.325300Z

it also happens when using a real device

zendevil 2021-03-11T10:54:40.325800Z

it doesn’t need to be idle. It happens even when the app is being used

thheller 2021-03-11T11:02:23.326500Z

I don't know. what happens if you open a browser on the device/emulator and open the UI? http://the-ip:9630? is that getting disconnected as well?

zendevil 2021-03-11T11:06:30.326900Z

@thheller how do I find the-ip?

thheller 2021-03-11T12:23:17.327400Z

the ip of your computer

zendevil 2021-03-11T12:50:28.327800Z

that gives “safari cannot open the page because it could not connect to the server”

zendevil 2021-03-11T12:50:41.328Z

I googled “my ip”

thheller 2021-03-11T12:51:25.328500Z

that likely led you to a site telling you your public IP which is not the IP you have on your local network

thheller 2021-03-11T12:51:31.328700Z

what OS are you on?

zendevil 2021-03-11T12:54:48.328900Z

macOS

thheller 2021-03-11T12:55:17.329100Z

https://osxdaily.com/2010/11/21/find-ip-address-mac/

thheller 2021-03-11T12:55:57.329600Z

ancient article I guess but I think the info is still there somewhere

zendevil 2021-03-11T12:58:00.329800Z

i see the following:

zendevil 2021-03-11T12:58:10.329900Z

thheller 2021-03-11T13:00:49.330300Z

yes that is the shadow-cljs UI

thheller 2021-03-11T13:01:06.330800Z

when its websocket disconnects you should get a big fat red box on the top

zendevil 2021-03-11T13:01:32.331500Z

i just saw the error and the warning in the app. Then opened safari. No difference

thheller 2021-03-11T13:01:40.331600Z

keep the browser open

thheller 2021-03-11T13:02:10.332200Z

do nothing. just wait. if you get no red box for 5min or whatever then that socket is not disconnecting

thheller 2021-03-11T13:02:22.332600Z

so the cause of you problem must be somewhere related to your app/react-native

thheller 2021-03-11T13:03:17.333100Z

if it also disconnects I still don't have a clue but at least we can rule out that the app is the cause

zendevil 2021-03-11T13:06:47.333300Z

okay, no red box for five minutes

thheller 2021-03-11T13:08:46.334Z

and the UI still works? you are on a kind of old version and I can't remember if that version already had the big red box

zendevil 2021-03-11T13:09:12.334500Z

So I changed to this:

(defn init []
  (dispatch [:register-db])
  (render-root "Humboi" (as-element [view];;[root-comp]
                                    )))
Basically removed the root-comp with a rn view

zendevil 2021-03-11T13:09:22.335Z

And I do see the warning and the error

thheller 2021-03-11T13:09:34.335300Z

ok so it is definitely connected

thheller 2021-03-11T13:10:17.335800Z

yeah sorry can't help further. I don't use react-native and don't have a clue how its networking works or how you'd go about debugging it

thheller 2021-03-11T13:10:33.336100Z

seems to be app related if the browser works fine

zendevil 2021-03-11T13:22:03.337300Z

could it be because of the three warnings that I’m getting? I don’t know how to get rid of them:

------ WARNING #1 - :fn-arity --------------------------------------------------
 Resource: re_frisk/trace.cljs:27:11
 Wrong number of args (1) passed to reagent.impl.component/do-render
--------------------------------------------------------------------------------

------ WARNING #2 - :fn-arity --------------------------------------------------
 Resource: re_frisk/trace.cljs:31:54
 Wrong number of args (1) passed to reagent.impl.component/do-render
--------------------------------------------------------------------------------

------ WARNING #3 - :undeclared-var --------------------------------------------
 Resource: re_frisk_remote/core.cljs:120:15
 Use of undeclared Var reagent.impl.component/static-fns
--------------------------------------------------------------------------------

Volodymyr Huzar 2021-03-11T14:43:12.345100Z

Hello! I want to get at least some kind of coverage for our cljs code. The generated by :target -> :karma js bundle is too big to be handled by karma-coverage plugin (JavaScript heap out of memory is thrown). The idea I had in my mind to split tests and source code into different modules and check coverage only on source part. But to be honest I have no idea on how to implement that. So my questions are: 1. Is it possible to use :modules for :build -> :target -> :karma ? I have tried and it seems they are ignored 2. Can we use namespace regex for :modules -> :entries ? I have tried :entries [".*-tests"] but it doesn’t work

thheller 2021-03-11T15:13:01.347400Z

@vguzar sorry I went over this with someone else not too long ago but I cannot remember any details. I have never used karma-coverage and I don't know what it needs to work. :modules is not supported by :target :karma. the target however is very little code so you can maybe figure out what you need and modify it to fit your needs. see https://github.com/thheller/shadow-cljs/blob/d810a0f5e1b1c78f15e0365ce7a05cba16f0ca70/src/main/shadow/build/targets/karma.clj

thheller 2021-03-11T15:16:56.347700Z

don't know what this does so don't have a clue if this affects anything. looks unlikely but I can't be sure.

Nolan 2021-03-11T15:33:19.354Z

hey @thheller! we're working on using one of the libraries we build with shadow from React Native. the library depends both directly and transitively on node's crypto module. i'm not super familiar with RN and its tooling, but it seems to be a well-recognized limitation that the crypto module needs to be browserified to some degree in order to be used, so all the proposed solutions trickle down into the build process. does this seem like something we could solve by tweaking shadow configuration? we've tried using :target :react-native and a few ways of redirecting :resolve, but the transitive dependency seems to retain require('crypto') somewhere or another. most recently weve been looking into ways of combining :js-provider :require with whatever polyfills crypto in :target :browser. let me know your thoughts and how you might approach this, it would be pretty awesome to get this working

Volodymyr Huzar 2021-03-11T15:34:12.354500Z

@thheller thanks for the answer. probably there is no sense to spend too much time on karma coverage if it doesn’t work out of the box as it gives coverage for js output code instead of source code. I am considering using https://github.com/lambdaisland/kaocha-cljs instead of karma which looks like supports coverage out of the box but lets see. I’ll come back to this later in case kaocha will not help here

thheller 2021-03-11T15:37:52.356100Z

@nolan use :target :react-native and follow whatever react-native instructions are for using the crypto module. there should be some? this needs to be resolved in the react-native configuration side of things. something in metro probably. no clue how.

thheller 2021-03-11T15:38:38.357200Z

:target :browser is not meant for react-native and don't waste your time trying to adjust it.

👍 1
🙏 1
Nolan 2021-03-11T15:42:11.358400Z

yeah, i thought the process for using crypto from metro would have a lot more documentation, but everything i've been able to find seems somewhat poorly supported. i was hoping to shield consumers of the library from a change to their build process, but it seems that might not be the best route.

Nolan 2021-03-11T15:48:08.358700Z

really appreciate the help. i was definitely going to sink a number of hours into twiddling target/provider configuration, so youve saved me that at the very least

thheller 2021-03-11T15:49:58.358900Z

well it might work with some configuration but it might get verbose

thheller 2021-03-11T15:50:15.359100Z

there is :js-options {:keep-as-require #{"react-native"}} for example

thheller 2021-03-11T15:50:36.359300Z

so you can set :js-provider :shadow and it'll bundle every JS require except for those mentioned in :keep-as-require.

thheller 2021-03-11T15:51:02.359500Z

so if you mention ALL but crypto that might work. fairly undesirable but it might work

thheller 2021-03-11T15:52:48.359700Z

oh nvm ... :js-provider :require is hardcoded for :react-native

Nolan 2021-03-11T15:55:58.359900Z

huh, very interesting. i will spend some time with this. at this point im primarily curious/ready to learn more about how this all works in shadow . i highly admire how easy it has been to grok how the config comes together

thheller 2021-03-11T15:57:33.360100Z

well this line is currently what would prohibit testing this with :js-provider :shadow and :keep-as-require https://github.com/thheller/shadow-cljs/blob/ea54e4b943c762645178303778aef094387f1a85/src/main/shadow/build/targets/react_native.clj#L131

thheller 2021-03-11T15:58:05.360500Z

you can take this file, put it on your classpath in the proper location and change that

thheller 2021-03-11T15:58:17.360700Z

maybe that works

Nolan 2021-03-11T16:01:49.360900Z

indeed, indeed. ill try it! a local shadow repo is something ive wanted to need for a long time. thanks a ton! 🙏

Nolan 2021-03-11T16:05:37.361100Z

i found this metro solution (https://github.com/brix/crypto-js/pull/259#issuecomment-588201011), which is the best way ive been able to find to do it generally (assuming it works). but im still going to see if im able to produce an artifact that doesnt need it directly from shadow, since i think that would be a pretty neat capability

thheller 2021-03-11T16:28:43.361400Z

don't need a full shadow-cljs repo. just literally copy that one file into your classpath and use it 🙂

naomarik 2021-03-11T17:12:00.363900Z

What JDK do you guys recommend for M1 mac? I've tried openjdk 16, tons of reflection errors. Zulu openjdk8 for macos/ARM and it works but the watch function seems to pick up changes extremely slowly. The only thing that's fast for watch is adoptjdk8 but it's x64 and launches very slow.

naomarik 2021-03-11T17:17:57.365Z

By pick up changes slow, I mean editing cljs files and saving takes a few seconds before anything happens... compiles fast though.

thheller 2021-03-11T17:19:20.365800Z

I use openjdk 15. watch being slow is caused by big sur. upgrading shadow-cljs should fix it

naomarik 2021-03-11T17:19:35.366100Z

cool will try upgrading it now then!

thheller 2021-03-11T17:20:03.366500Z

:fs-watch {:hawk false} in shadow-cljs.edn should also work

naomarik 2021-03-11T17:22:28.366900Z

Thanks @thheller, lightning fast now.

naomarik 2021-03-11T17:22:47.367300Z

Upgraded to latest version works fast now.

2021-03-11T19:08:41.368700Z

I'm trying to debug a case that has cropped up in my project, where a release build with optimizations :simple breaks due to loading errors, but optimizations :advanced works fine. I get things like:

2021-03-11T19:08:57.368800Z

2021-03-11T19:09:11.369300Z

Any clue on how you would debug this? I'm completely mystified by it.

thheller 2021-03-11T19:15:51.369700Z

not a clue. look at the code location I guess.

2021-03-11T19:16:54.370400Z

What does it mean to do a release build with simple optimizations? It's still minified I suppose.

thheller 2021-03-11T19:17:17.370900Z

you can set :js-options {:minimize-require false} in your build config. that'll at least make it more obvious which files fail

2021-03-11T19:17:31.371100Z

Ok, thank you - that will be helpful I am sure.

thheller 2021-03-11T19:17:40.371400Z

shadow-cljs release app --debug might also help

2021-03-11T19:18:23.371800Z

Ok, thanks for that as well. I will keep banging my head against this ...

2021-03-11T19:18:31.372100Z

(This didn't used to happen)

2021-03-11T19:23:31.372700Z

Ok, interesting. It is a js library I use called Automerge that is failing to load for some reason.

2021-03-11T19:23:33.372900Z

I also see this:

2021-03-11T19:23:41.373100Z

Resource: node_modules/automerge/src/automerge.js:2
 constant module$node_modules$automerge$src$automerge assigned a value more than once.
Original definition at externs.shadow.js:20

2021-03-11T19:23:51.373400Z

Does that mean that the inferred externs don't match somehow?

thheller 2021-03-11T19:29:52.373700Z

hmm odd. not sure.

2021-03-11T19:32:31.374200Z

Ok, well, thanks for the insight. I am going to go have dinner, and I will try to pick this up tomorrow after getting some more sleep. Have a nice night!

hadils 2021-03-11T20:32:28.376400Z

I am trying to convert the JS statement:

import AsyncStorage from '@react-native-async-storage/async-storage';
into shadow-cljs:
(ns com.yardwerk.mobile-ui.async-storage
  (:require
    [cognitect.transit :as t]
    [com.fulcrologic.fulcro-native.alpha.components :as c :refer [react-factory]]
    ["@react-native-async-storage/async-storage" :default AsyncStorage]))
and I am getting the following error:
undefined is not an object (evaluating 'shadow.js.shim.module$$react_native_async_storage$async_storage.default')
I am scratching my head. I checked everything -- the package.json, reloaded node_modules, etc. Anybody run into this problem?

thheller 2021-03-11T20:39:43.377400Z

try ["@react-native-async-storage/async-storage" :as AsyncStorage]. your translation is otherwise correct but sometimes packages don't actually have a default export and are bundled as commonjs

thheller 2021-03-11T20:40:25.378200Z

I assume you reloaded your RN app after making that change as "new" JS dependencies cannot be loaded via hot-reload

hadils 2021-03-11T20:42:18.378800Z

Yes, I did. Now the call to setItem fails:

undefined is not an object (evaluating 'shadow.js.shim.module$$react_native_async_storage$async_storage.setItem')

hadils 2021-03-11T20:42:40.379200Z

I shut everything down and restarted...

thheller 2021-03-11T20:43:44.379700Z

just try (js/console.log AsyncStorage) or so to find out what it actually is

hadils 2021-03-11T20:43:52.379900Z

Ok.

hadils 2021-03-11T20:44:24.380100Z

It's underfined.

thheller 2021-03-11T20:45:13.380600Z

did you install it properly? maybe it needs an extra install step besides npm install

thheller 2021-03-11T20:45:23.380900Z

some react-native packages seem to require that

thheller 2021-03-11T20:45:58.381500Z

I don't use react-native so I don't have a clue

hadils 2021-03-11T20:51:27.381700Z

Ok. Thanks.

hadils 2021-03-11T21:29:24.383Z

@thheller A friend helped me solve the problem. You need to import it into a part of the working app. I was writing a library so it didn't know about it from the root of the app...