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.looks like the app is losing the websocket connection to the shadow-cljs instance. maybe the device going to sleep or so?
i’m running this on the simulator currently, and it has never gone to sleep
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?
it also happens when using a real device
it doesn’t need to be idle. It happens even when the app is being used
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?
@thheller how do I find the-ip?
the ip of your computer
that gives “safari cannot open the page because it could not connect to the server”
I googled “my ip”
that likely led you to a site telling you your public IP which is not the IP you have on your local network
what OS are you on?
macOS
ancient article I guess but I think the info is still there somewhere
i see the following:
yes that is the shadow-cljs UI
when its websocket disconnects you should get a big fat red box on the top
i just saw the error and the warning in the app. Then opened safari. No difference
keep the browser open
do nothing. just wait. if you get no red box for 5min or whatever then that socket is not disconnecting
so the cause of you problem must be somewhere related to your app/react-native
if it also disconnects I still don't have a clue but at least we can rule out that the app is the cause
okay, no red box for five minutes
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
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 viewAnd I do see the warning and the error
ok so it is definitely connected
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
seems to be app related if the browser works fine
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
--------------------------------------------------------------------------------
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
@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
don't know what this does so don't have a clue if this affects anything. looks unlikely but I can't be sure.
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
@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
@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.
:target :browser
is not meant for react-native and don't waste your time trying to adjust it.
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.
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
well it might work with some configuration but it might get verbose
there is :js-options {:keep-as-require #{"react-native"}}
for example
so you can set :js-provider :shadow
and it'll bundle every JS require except for those mentioned in :keep-as-require
.
so if you mention ALL but crypto
that might work. fairly undesirable but it might work
oh nvm ... :js-provider :require
is hardcoded for :react-native
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
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
you can take this file, put it on your classpath in the proper location and change that
maybe that works
indeed, indeed. ill try it! a local shadow repo is something ive wanted to need for a long time. thanks a ton! 🙏
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
don't need a full shadow-cljs repo. just literally copy that one file into your classpath and use it 🙂
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.
By pick up changes slow, I mean editing cljs files and saving takes a few seconds before anything happens... compiles fast though.
I use openjdk 15. watch being slow is caused by big sur. upgrading shadow-cljs should fix it
cool will try upgrading it now then!
:fs-watch {:hawk false}
in shadow-cljs.edn should also work
Thanks @thheller, lightning fast now.
Upgraded to latest version works fast now.
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:
Any clue on how you would debug this? I'm completely mystified by it.
not a clue. look at the code location I guess.
What does it mean to do a release build with simple optimizations? It's still minified I suppose.
you can set :js-options {:minimize-require false}
in your build config. that'll at least make it more obvious which files fail
Ok, thank you - that will be helpful I am sure.
shadow-cljs release app --debug
might also help
Ok, thanks for that as well. I will keep banging my head against this ...
(This didn't used to happen)
Ok, interesting. It is a js library I use called Automerge that is failing to load for some reason.
I also see this:
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
Does that mean that the inferred externs don't match somehow?
hmm odd. not sure.
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!
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?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
I assume you reloaded your RN app after making that change as "new" JS dependencies cannot be loaded via hot-reload
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')
I shut everything down and restarted...
just try (js/console.log AsyncStorage)
or so to find out what it actually is
Ok.
It's underfined.
did you install it properly? maybe it needs an extra install step besides npm install
some react-native packages seem to require that
I don't use react-native so I don't have a clue
Ok. Thanks.
@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...