Fork me on GitHub
#shadow-cljs
<
2020-02-26
>
kaosko07:02:14

related to requiring js files. now the js file wants to import stuff from the npm module that I've already required via shadow. How do I refer to it? as is, I get 'Cannot access "../../../build/three.module.js" from "jsm/misc/Ocean.js".' which makes a lot of sense. I suppose I could point :source-paths to the whole node-modules but it kind of defeats the purpose

Saikyun10:02:04

I've fiddled around a lot with cljs + three.js. if you can give me a repro-repo I can help you 🙂

kaosko17:02:50

thanks @UCG86LJFN this is not open source at the moment. anyway, you might be able to help me with it. Able to fix the files in /jsm to require three as a module instead of path, but they also import a lot of stuff from three that now hasn't been exported. How do I resolve that, any idea?

kaosko15:03:22

just for completeness, the issue was that shadow compiler doesn't ES6 style module imports, i.e.

import {
 Vector2
} from "three";
instead, I had to write it like this:
import * as three from 'three';
const { Vector2 } = three;

Saikyun13:03:49

seems strange to me. I've been able to do import { Vector2 } from "three". either way, nice that you fixed it 🙂

tekacs08:02:12

I’d like to run /just/ the hot-reload and CLJS REPL parts of shadow-cljs, without exposing my computer’s clj-eval/etc. through the websocket to anyone passing by. I’ve been live editing my app in front of astonished (local network) users using shadow for some time now. Unfortunately, I can’t leave it running unsupervised or :gasp: expose it on the web, since the websocket/dashboard has clj-eval functionality, which opens up my computer to having arbitrary code run on it. If I’ve missed how to do this I’d love to hear about it — or if it’s not possible, I’d love to add support for it (perhaps whitelisting :supported_ops / :op ?)

zilvinasu08:02:23

sorry if this is a dumb question, if it is listening on localhost rather than 0.0.0.0 how is it being exposed ?

thheller08:02:54

it is listening on 0.0.0.0 by default

👍 4
thheller08:02:04

you can change set by setting :http {:host "localhost"} in shadow-cljs.edn

thheller08:02:41

but it is likely a good idea to run a local firewall?

tekacs17:02:50

@thheller my hope /was/ to run it in a way that’s accessible to multiple folks and keep running it for a while, so that it hot reloads for all of them. That is — I’d like to expose the hot reload and CLJS REPL aspects without the ‘run code on my machine.’ aspects. My suggested thought was to filter the operations that can be sent over the websocket, so as not to include :clj-eval/etc. Does that make sense?

thheller17:02:50

I think I may add a basic "trusted" check. so that some operation are only allowed from trusted clients. basically an IP check. defaulting to local only but maybe letting you add IPs via config

thheller18:02:17

making those per OP is a bit overkill though

tekacs18:02:11

Mm, honestly even just having a configuration flag to turn off all of the ‘trusted’ operations would be super welcome.

tekacs18:02:45

But IP whitelisting would make it super effective (again, just across all trusted ops) — I could still get in to debug but allow others to see and hot reload it.

tekacs18:02:52

Let me know if I can help at all.

tekacs18:02:10

for what it's worth, I set up the combination of: • Port forwarding 3000 -> 443 & 9630 to a domain • SSL with a keystore + {:closure-defines {shadow.cljs.devtools.client.env.ssl true}} and then was able to send folks to https://test-app.example.com and have them see my changes from wherever they were in real-time and debug their issues from the REPL (or the browser view, or even tap> from the clients and Inspect the results). It has made for a really interesting and capable development experience -- if the 'trusted/unsafe' operations could be IP whitelisted as you suggest, I would recommend this to most folks and see if I could bottle up the pattern and write something about it. :)

thheller18:02:10

well as soon as you port forword the IP check will fail because the IP will be whatever does the tunneling 😛

tekacs18:02:37

Haha I did think of that and wonder (given that your TCP termination would be local) — and then wrote it off without considering further.

thheller18:02:26

but hot-reloading is separate from that anyways

tekacs18:02:35

A cookie could work, perhaps? Trying not to create work. 😅

tekacs18:02:58

You already have ‘secret’ set, IIRC

thheller18:02:03

the UI stuff already uses a cookie but anyone visiting the UI can get that cookie

tekacs18:02:18

Ah and it’s the same for every client?

tekacs18:02:33

If it were stored locally, we could whitelist it from the server side

thheller18:02:35

there is not "login" so yeah

tekacs18:02:41

If it were unique per client

tekacs18:02:45

Just a UUID

thheller18:02:12

nah the secret is just a basic check so that you can't open the websocket without opening the UI first

thheller18:02:32

really basic security check really

tekacs18:02:00

I guess I could kill the HTTP side of the channel and only allow HTTP 101 to secure it 😂 — though I suspect it’s sent early :P

tekacs18:02:05

But more seriously

thheller18:02:28

first of all you need to separate what you want to allow access to in the first place

thheller18:02:36

hot-reload has nothing to do with any of the UI parts

thheller18:02:48

so blocking the UI is probably good enough

tekacs18:02:00

Isn’t it over WS on the same port though?

thheller18:02:11

yes, but it doesn't have to be

tekacs18:02:57

Would cljs REPL also be on the same WS?

tekacs18:02:14

Because if there were three ports

thheller18:02:30

ok a bit of terminology so we understand each other

thheller18:02:44

runtime: anything running JS (eg. browser)

thheller18:02:00

tool: anything sending tool command (eg. eval)

thheller18:02:07

relay: shadow-cljs server

thheller18:02:42

access to the relay is open so you can open a runtime anywhere

thheller18:02:01

ie. multiple browser, devices etc

thheller18:02:16

tool connections should probably be restricted somehow

thheller18:02:28

the compiled code is NOT a tool, it is only a runtime

thheller18:02:42

so there need to be no "security" there imho

thheller18:02:17

restricting the tool access based on IP is easy

thheller18:02:26

it also doesn't need to run on :9630

thheller18:02:36

just currently does for (my) convenience

tekacs18:02:00

Right, so three ports would be ideal from my point of view

tekacs18:02:10

As in — 3000, 9630 are forwarded

tekacs18:02:17

The third port I could just not forward

tekacs18:02:27

And that would work perfectly from my POV

tekacs18:02:35

People could access the site and runtime but not tool

tekacs18:02:19

And the runtime has hot reload and the connection to the relay for cljs REPL into those clients IIUC

tekacs18:02:34

Does that seem correct?

tekacs18:02:47

And thank you for taking the time to talk

thheller18:02:35

well as soon as the tool access is restricted the UI might as well be too

thheller18:02:39

since it won't work without it

thheller18:02:49

I'll see if I can figure something out

thheller08:02:45

@kaosko you just need to rewrite the require in those files to use the regular threejs from npm, ie. not a path

👍 4
xlfe10:02:56

hello channel. thanks for shadow-cljs - i'm just getting started and trying to understand if I am working with shadow-cljs correctly. I have a shadow-server setup and shadow is watching my :app for a :browser target. I can connect in the browser, etc and my app works there without errors. I am using vim-fireplace to connect to the nREPL and edit code, etc. One thing I cannot get working is omni-completion for npm modules that shadow-cljs is handling.

thheller10:02:57

no clue what omni-completion is so you'll have to ask the vim-fireplace folks

thheller10:02:03

likely it just doesn't support npm modules

xlfe10:02:15

For example, in one file i have a (:require such as ["@material-ui/core" :as mui]. I cannot get omni-complete to complete anything after mui/ namespace

xlfe10:02:16

ah right

xlfe10:02:30

i beleive it calls a nREPL message with :completion or something

xlfe10:02:51

its used to tell you what is defined in a namespace on the fly (based on what you're typing)

xlfe10:02:13

does shadow-cljs "know" what externs each npm module provides?

xlfe10:02:50

sorry I think I mean "exports" rather than "externs"

thheller10:02:06

not precisely no

xlfe11:02:26

hmm ok. I should probably do a bit more thinking about the problem and digging into source. I used to have completion working (for example with material-ui) but that was using a cljsjs module where each export from the node module was explicitly defined in cljs

xlfe11:02:31

thanks for your help

thheller11:02:42

so what do people think. would your development setup be broken if it defaulted to localhost only? https://github.com/thheller/shadow-cljs/issues/660

hlolli13:02:52

given the fact that all human friendly distro default /etc/hosts to forward to localhost, then I wouldn't worry about defaulting to it. The people that have changed it (hopefully) know what they are doing and I guess could configure their setup differently.

isak15:02:36

it sounds fine to me too

magra18:03:52

I vote secure default

tekacs18:02:10

for what it's worth, I set up the combination of: • Port forwarding 3000 -> 443 & 9630 to a domain • SSL with a keystore + {:closure-defines {shadow.cljs.devtools.client.env.ssl true}} and then was able to send folks to https://test-app.example.com and have them see my changes from wherever they were in real-time and debug their issues from the REPL (or the browser view, or even tap> from the clients and Inspect the results). It has made for a really interesting and capable development experience -- if the 'trusted/unsafe' operations could be IP whitelisted as you suggest, I would recommend this to most folks and see if I could bottle up the pattern and write something about it. :)

neupsh19:02:45

Hello, does anyone have a nice little template to write web extensions (for firefox and chrome) using shadow-cljs?

darwin20:02:50

for chrome we have an example here, not sure if it is little or particulary nice tough 🙂

neupsh20:02:48

Thanks 🙂 Do you think it works with firefox as well?

darwin20:02:59

100% doen’t actually I have no idea

thheller20:02:12

I think firefox extensions are somewhat similar so it might work

thheller20:02:39

the :chrome-extension target actually doesn't do anything chrome specific so it might work

neupsh20:02:40

Thanks. I will give it a try

neupsh20:02:33

So, i gave it a try today: • built the example using shadow-cljs • loaded the extension in chrome: worked • loaded the extension in firefox: worked with some warnings