Fork me on GitHub
#shadow-cljs
<
2019-05-04
>
Stefan15:05:50

Can shadow-cljs support a module like this in a react-native target? https://github.com/IgorBelyayev/React-Native-Local-Resource

denik22:05:45

GIVE THIS MAN MORE STARS

😂 4
thheller15:05:00

not sure I understand what that does but looks like a native module so shadow-cljs has nothing to do with that

thheller15:05:24

but you kinda don't need it

Stefan19:05:27

> Don’t include 5mb of text this way, load it at runtime instead. I guess that rules my use case out, the compiled JS code that I want to load is already 4.5mb and I hardly have any code of my own yet 😉

thheller19:05:06

I guess its less of an issue in react-native since its just loading locally

Stefan19:05:08

That’s true. Everything ends up in the app bundle one way or another.

thheller15:05:30

you can use that other thing too though

thheller15:05:44

just use (js/require "./my_resource.txt")

Stefan15:05:02

ahhh js/require right

thheller15:05:03

just need to adjust the path properly

thheller15:05:20

so probably (js/require "../my_resource.txt") or so

thheller15:05:37

depends on where you keep the file

Stefan15:05:23

Cool thanks! I’ll also check the other method you mentioned! 👍

Stefan15:05:18

(In this case the file that I’ll be reading is the output of another shadow-cljs target 🙂 )

thheller15:05:33

right. how is that going? 😛

Stefan15:05:22

Still plodding along 🙂 I’m going to write a blog post about this when I’m done, titled something like “the 42 things I learned this holiday about react native, webviews, web audio in react native, and doing all that using clojurescript” 🙂

👍 4
Alexander17:05:49

Hey folks – I'm trying to get browser hot loading and the browser REPL working when shadow is running behind a secure HTTPS -> HTTP proxy (nginx w/proxy_pass). My app loads over https:// but tries to connect the primary server's websocket using ws://, which causes a mixed content error. Is there a way to get a wss:// scheme without telling shadow to handle the SSL itself (because it's already behind a secure proxy)?

martinklepsch20:05:18

@thheller on the proxy support stuff (I'm working with Alexander) — with the :devtools-url parameter we can get things to work but it's a little impractical in the context of every developer having their own URL and reading this configuration from the environment before starting shadow-cljs. We were wondering if it might make sense to default to wss:// if the devtools are loaded on a page that already uses https://? This would cover our use case without additional configuration and might be a reasonable default? Could be this breaks something else of course but just wanted to give a bit more context on the situation.

thheller21:05:46

the issue is that by default shadow-cljs connects to itself

thheller21:05:07

so it'll connect to

thheller21:05:38

if it connects to that'll fail if shadow-cljs has no ssl configured

thheller21:05:52

you can just configure ssl in shadow-cljs then it'll use wss anyways

thheller21:05:04

but that depends on having access to the cert

martinklepsch22:05:01

right, in this case shadow doesn't have access to the cert because it sits behind a proxy that shadow doesn't know about

martinklepsch22:05:01

I see how the https -> wss default could break things though so I guess we'll configure things using the devtools url option

thheller22:05:37

If you can think of something that would work for your case I can take a look at implementing it

thheller22:05:50

just not sure what your setup and problem is

martinklepsch23:05:37

We run shadow locally behind something custom (similar to ngrok) that forwards shadow's ports. The idea is that you can access that on other devices or that coworkers can access it from anywhere. The server is nginx with custom certs set up. Shadow does not know about these certs. This is intentional since we still want to be able to access things via localhost. In the case of a request going through nginx https:// is used but with out the devtools-url Shadow will try to use ws:// which causes "insecure content" errors. Does this clarify things a bit more?

thheller23:05:52

so by default it will connect to the document hostname + server port

thheller23:05:20

so if you open it'll connect to

thheller23:05:52

hmm just setting the port doesn't work though

thheller23:05:06

why does everyone need a custom :devtools-url?

thheller23:05:26

you could just add a local hosts entry and use a hostname isntead of ip?

martinklepsch23:05:05

I'm not sure I understand the hosts suggestion. Not 100% if relevant but we'd have an instance of this application for every coworker, each with a different public URL

martinklepsch23:05:05

> if it connects to that'll fail if shadow-cljs has no ssl configured I think my thinking here is: if shadow is loaded on an https:// page — wouldn't it make sense to assume the websocket connection should also use wss://. In fact in most browsers it just won't work otherwise due to insecure content restrictions, I think?

thheller23:05:26

as I explained .. it can't

thheller23:05:00

the issue is that shadow-cljs connects to itself DIRECTLY. it does not go through your nginx

thheller23:05:33

thats what :devtools-url is for .. it tells it where to connect to instead

martinklepsch23:05:37

ahh, so it doesn't use whatever is in the URL bar and will always use localhost?

martinklepsch23:05:50

Is that what you're saying? That might be where my confusion is coming from 😅

thheller23:05:52

it does use the URL from the document

thheller23:05:54

just not the port

thheller23:05:10

the default is using document.location.hostname

thheller23:05:24

and it adds the server port

thheller23:05:41

so becomes

martinklepsch23:05:48

right, we expose that server port as shadow expects it

thheller23:05:58

since wouldn't answer the websockets

martinklepsch23:05:14

right — so if it takes the hostname, it could also take the protocol?

thheller23:05:27

you are not listening to me 😛

martinklepsch23:05:34

(sorry if I'm asking naive questions, just trying to wrap my head around this)

thheller23:05:50

it cannot take the protocol because it cannot connect to since that has no ssl configured

martinklepsch23:05:14

right, but in our case it has 😄

martinklepsch23:05:30

because we proxy stuff through to shadow

thheller23:05:41

you proxy 9630?

thheller23:05:45

I'm confused now ... I was assuming your proxy is serving the normal document. so or whatever that is, ie. port 443

martinklepsch23:05:12

yes, it's doing that but it's also proxying 9630 otherwise the document served under https:// couldn't connect to that port

thheller23:05:46

I'm so confused right now

martinklepsch23:05:43

sorry, I'll come back in a minute with better details

martinklepsch23:05:54

thanks for all your help and sorry this is a bit confusing 😄

thheller23:05:24

you have configured an additional server that only acts as a proxy

thheller23:05:52

so forwards port 443 AND 9630 to someone elses machine?

thheller23:05:21

and as well

martinklepsch23:05:35

yes. in practice both ports forward to a port on localhost and those ports are ssh forwarded to a local machine

thheller23:05:35

but both foo and bar are running the same shadow-cljs build?

martinklepsch23:05:14

no, foo and bar might be shadow-cljs builds on two different machines (i.e. people's computers)

thheller23:05:51

no what I mean is the same config is used for those builds?

thheller23:05:15

thats why :devtools-url is a problem in the first place?

martinklepsch23:05:38

what we'd have to do with how things work now is have a different devtools-url for each machine (arguably could be much worse)

martinklepsch23:05:55

sounds like we're approaching shared understanding 🎉

thheller23:05:59

ok. so I can add a simple :force-ssl option so it just uses wss

thheller23:05:18

since now ssl is dependent on having ssl configured in shadow-cljs

martinklepsch23:05:29

yeah, that's kind of what we were thinking of but it should only force SSL if the document is loaded via https

martinklepsch23:05:48

because for local dev we will still mostly want to use basic localhost stuff

martinklepsch23:05:26

right, I guess we'd need to customize the (when ssl ,,,) somehow so that it also takes the document's protocol into account

thheller23:05:42

well you could just set it directly 😉

thheller23:05:31

I'll figure out a way to do this tomorrow 😛

martinklepsch23:05:01

you mean set ssl via goog-define?

martinklepsch23:05:52

awesome! no urgency to this to feel free to sit on it for a bit 🙂

martinklepsch23:05:45

Good night & thanks again 🙌

Alexander17:05:35

@thheller thank you, that helped

Stefan18:05:30

@thheller I’ve been following this channel for a while now. Would it be an idea to add a troubleshooting / FAQ section to your user manual?

thheller18:05:29

you tell me 😉 I rarely read the docs myself 😛

Stefan18:05:01

hehe I didn’t expect you would need to 😉

Stefan18:05:18

Don’t get me wrong, I think the manual is very good. It’s really complete and has a lot of detail. I feel that it can be even better somehow, I’m just not sure exactly how. Maybe it’s because I’m a beginner in CLJ(S).

Jon04:05:28

if those conversation happen on GitHub issues, people would find them with Google..

Jon04:05:01

Google is the entry for FAQ.

thheller18:05:51

It can most definitely be better .. just takes a large amount of time and I also suck at writing

thheller18:05:06

so any suggestions are welcome

thheller18:05:34

oftentimes the problem is that you don't know what you are looking for

thheller18:05:41

so having such a huge document doesn't help

Stefan18:05:55

I think for me it’s maybe about the “information density” of the document. I’ll give it a thought.

Stefan18:05:44

Oh by the way the fact that it’s a one page document is awesome, it makes it very easy to search for things.

thheller18:05:35

if you know what you are searching for yes 😉

lilactown19:05:22

I was thinking the other day about having a search bar at the top and maybe some additional organization / tagging to enable searchability

lilactown19:05:43

typically what I do is open up the user guide, Ctrl-F what I’m looking for, if I don’t find it I come ask here 😛

Stefan19:05:07

Yeah me too, but indeed sometimes it is hard to know what exactly you’re looking for, especially as a beginner.

genRaiy19:05:07

I’m trying to get {:js-provider :shadow} working and hitting a few weirdo deps issues

genRaiy19:05:06

for example a library is calling require to throw an error but shadow insists the lib must be installed

genRaiy19:05:59

is there a way to ignore it?

thheller19:05:13

you can use :keep-as-require #{"crypto"} (in :js-options)

genRaiy19:05:37

oh, cool - thanks

thheller19:05:09

is crypto not a built-in for node? maybe its missing from my list

thheller19:05:35

hmm wait is this for the browser?

thheller19:05:42

or the one-file node thing?

genRaiy19:05:22

it’s for node, but yes it’s built in for node but not for earlier versions

thheller19:05:50

hmm weird its in the list though

thheller19:05:15

so :keep-as-require shouldn't do anything since its already in that set

genRaiy19:05:48

you’re right, same problem

genRaiy19:05:53

this is what I have….

thheller19:05:15

well maybe its just actually missing the crypto.randomBytes?

thheller19:05:38

oh you are missing the imporant bit

thheller19:05:57

:keep-native-requires true in :js-options

thheller19:05:26

otherwise it'll actually try to bundle everything

thheller19:05:44

(and in the crypto case use a polyfill package)

genRaiy19:05:53

I want it to bundle as much as needed - I can’t access npm in the deployed environment

genRaiy19:05:12

but OK I’ll add that in

thheller20:05:57

yes but its want you want

thheller20:05:18

native requires are just the node built-in packages so you don't need npm for that

thheller20:05:50

without :keep-native-requires it works like the browser which wouldn't have access to node built-ins so they need to be bundled too

genRaiy20:05:13

ah ok … I am a bad manual reader 🙂

thheller20:05:36

well its an alpha experimental everything will break kind of feature 😉

genRaiy20:05:00

yeah, it’s not playing out that well in real time

thheller20:05:44

you can just use the normal shadow-cljs stuff without :js-provider :shadow and post process the file with something like https://github.com/zeit/ncc

thheller20:05:05

thats probably a lot more reliable in practice

genRaiy20:05:21

ok, good to know - thanks

Stefan20:05:18

@thheller I think I just managed to load the code generated by my :browser target into a React Native Webview. I just injected the code, I’m not yet calling it. Would you expect that it is running a repl client (or what is the term)? Should I be able to connect to it, and if yes: how?

thheller20:05:08

REPL requires that watch is running

thheller20:05:52

and you probably need to configure :devtools-url since the default browser logic won't work https://shadow-cljs.github.io/docs/UsersGuide.html#_proxy_support

thheller20:05:16

:devtools-url "" or whatever your ip is

thheller20:05:35

no clue what the webview is capable of though

thheller20:05:23

try gaining access to the console output if possible

Stefan20:05:27

The webview should be the whole thing, the same thing that is powering Chrome/Safari, so websockets etc should be available

thheller20:05:29

so you can see if something is logged

Stefan20:05:53

Yeah well that’s not easy. I think I’ll have to use reactortron or something for that.

Stefan20:05:28

For debugging purposes I’m now just appending html to document.body.innerHTML 🙂

Stefan20:05:46

Actually reactortron won’t help either because it won’t redirect console.log output

Stefan20:05:59

Oh my it’s even easier than I imagined 🙂 🙂 🙂 It’s running a repl allright and I can simply use shadow-cljs cljs-repl to connect. Hurray! 🎉

Stefan20:05:32

Beat that, react-devtools, ha!

Stefan20:05:43

Did I mention shadow-cljs and you are awesome?! 🙂

😎 4
polymeris22:05:13

Hello A JS library I am trying to use (in the browser) is throwing with Uncaught TypeError: process.nextTick is not a function. I know next to nothing about JS/node/etc, so I might be wrong, but from what I gather, process is a node global that exposes that function, and shadow does mock part of that global which it then passes to the library when it's required: https://github.com/thheller/shadow-cljs/blob/master/src/main/shadow/js.js#L55 It does, however not mock or polyfill nextTick. So my question is: Can I monkey-patch shadow.js.process? How? Or can I somehow replace the whole process thing with a polyfill from webpack/browserify or similar? (I think the library is designed to run with webpack)

polymeris22:05:27

(i'd rather not add webpack to the build chain if I can avoid it)

thheller22:05:12

hmm yeah looks like my "ported" version of process is out of date

thheller22:05:46

you can just monkey patch it in your code via (gobj/set shadow.js/process "nextTick" js/goog.async.nextTick) or so

thheller22:05:24

might need to do it in a namespace that is required before the JS code

thheller22:05:30

in case the JS uses it directly on load

polymeris22:05:09

Thank you, I'll try that!

thheller22:05:01

don't forgot to require goog.async.nextTick and shadow.js in the namespace that does that