Fork me on GitHub
#clojurescript
<
2018-04-03
>
zentrope00:04:14

If you use :aot-cache, where does it cache the files?

mfikes01:04:41

@zentrope In your home directory, under .cljs/.aot_cache/<compiler-version>/<hash>/<ns-path>[.js|.js.map|.cljs|.cljs.cache.json]

zentrope01:04:21

Ah. The dot file inside a dot file. That’s why I didn’t see it in ~/.cljs. Thanks!

Alex Miller (Clojure team)02:04:53

that’s double secret probation

👍 4
🐒 4
🏠 4
Serge06:04:21

Can I use cljs with npm packages? How?

kah0ona07:04:37

I’m dealing with it now as well, but struggling a bit though

gklijs07:04:38

I heard multiple times it’s only working easy with shadow-cljs, https://github.com/thheller/shadow-cljs

kzeidler07:04:30

I think the last time I used Clojurescript was about 3 years ago. IIRC the emacs CIDER repl was by far the nicest repl shell for live programming, is that still the case?

pesterhazy08:04:58

@kzeidler yes, but some people use Cursive as well

pesterhazy08:04:23

there's other options, including Atom

kurt-o-sys09:04:32

getting npm modules work with cljs still seems to be hard. I know about npm-deps, but that doesn't work for all npm modules. I still stick to http://blob.tomerweller.com/reagent-import-react-components-from-npm . However, whenever I change :optimizations to something that is not none, that methods seems to fail (due to React being undefined)... Am I missing something here? (How to make optimizations work when importing react components from npm using the tomerweller approach?)

pesterhazy09:04:09

@kurt-o-sys I use the same technique. You'll need to set window.React

pesterhazy09:04:02

... looks like I misread your question

pesterhazy09:04:24

where do you set window.React, and how it used? From Reagent?

kurt-o-sys09:04:55

you mean this:

window.deps = {
    'react' : require('react'),
    'react-dom' : require('react-dom'),
    'react-player' : require('react-player'),
};

window.React = window.deps['react'];
window.ReactDOM = window.deps['react-dom'];

kurt-o-sys09:04:06

in src/js/main.js

kurt-o-sys09:04:40

(it all works with :optimizations :none)

pesterhazy09:04:04

so if you open the compiled result in chrome, do you see window.React from the devtools?

pesterhazy09:04:18

that's the first thing to check

kurt-o-sys09:04:02

oh, not sure... I do get an undefined where React should be 😛. Let me try the devtools thing in chrome.

kurt-o-sys09:04:54

hmmm, I really must be missing something: in devtools, my app.js looks different than the actual app.js file (even when using optimizations none): actual file (using a file browser)

var CLOSURE_UNCOMPILED_DEFINES = {};
var CLOSURE_NO_DEPS = true;
if(typeof goog == "undefined") document.write('<script src="/js/out/goog/base.js"></script>');
document.write('<script src="/js/out/goog/deps.js"></script>');
document.write('<script src="/js/out/cljs_deps.js"></script>');
document.write('<script>if (typeof goog == "undefined") console.warn("ClojureScript could not load :main, did you forget to specify :asset-path?");</script>');
document.write('<script>goog.require("process.env");</script>');
document.write('<script>goog.require("ui_app.prod");</script>');
fetched file (using devtools)
if(typeof Math.imul == "undefined" || (Math.imul(0xffffffff,5) == 0)) {
    Math.imul = function (a, b) {
        var ah  = (a >>> 16) & 0xffff;
        var al = a & 0xffff;
        var bh  = (b >>> 16) & 0xffff;
        var bl = b & 0xffff;
        // the shift by 0 fixes the sign on the high part
        // the final |0 converts the unsigned value into a signed value
        return ((al * bl) + (((ah * bl + al * bh) << 16) >>> 0)|0);
    }
}

!function(e){var t={} ...

kurt-o-sys09:04:28

(also after clearing browser cache)

kurt-o-sys09:04:48

But that boils it down to: it does work in dev, not in prod, no matter how I set optimizations...

pesterhazy09:04:46

• rule out caching issues by trying a different browser

kurt-o-sys09:04:50

:cljsbuild {:builds ...
                       :app         {:source-paths ["src/cljs" "src/cljc" "env/dev/cljs"]
                                     :figwheel     {:on-jsload ui-app.core/mount-root}
                                     :compiler     {:main          ui-app.dev
                                                    :asset-path    "/js/out"
                                                    :output-to     "target/cljsbuild/public/js/app.js"
                                                    :output-dir    "target/cljsbuild/public/js/out"
                                                    :source-map    true
                                                    :optimizations :none
                                                    :foreign-libs  [{:file     "public/js/bundle.js"
                                                                     :provides ["cljsjs.react" "cljsjs.react.dom" "webpack.bundle"]}]
                                                    :pretty-print  true}}
                       ...
                       :hosted      {:source-paths ["src/cljs" "src/cljc" "env/prod/cljs"]
                                     :compiler     {:main          ui-app.prod
                                                    :asset-path    "/js/out"
                                                    :output-to     "resources/public/js/app.js"
                                                    :output-dir    "resources/public/js/out"
                                                    :source-map    true
                                                    :optimizations :none
                                                    :foreign-libs  [{:file     "public/js/bundle.js"
                                                                     :provides ["cljsjs.react" "cljsjs.react.dom" "webpack.bundle"]}]
                                                    :pretty-print  true}}
 

pesterhazy10:04:57

• deep clean all your state (remove target etc.)

pesterhazy10:04:33

• check the files loaded in your network tab and verify you're getting the right ones (does your index.html point to the right files?)

kurt-o-sys10:04:06

deep clean: done right files: yes

kurt-o-sys10:04:37

(well, it points to the right url 🙂 )

kurt-o-sys10:04:42

oh... sh*t, this is something rather unexpected. Seems to work fine with https, but not with http. Will dive deeper into it - http should redirect to https anyway.

pesterhazy10:04:23

nginx/apache config issue?

kurt-o-sys10:04:25

guess so... it's a hosted service, so I have to check whether with them.

kurt-o-sys10:04:14

thx for just walking me through - things can be pretty weird from time to time 😛

pesterhazy10:04:34

np, everyone goes through this type of stuff

pesterhazy10:04:52

pro trip: try tracing the request with curl -i

ajs10:04:18

I need a recommendation on best practice/library for encrypting something client side and then decrypting it server side (Clojure) so the data is encrypted on the wire even in absence of SSL

thheller10:04:59

short answer is: use SSL.

👍 12
kah0ona10:04:16

yes... Let the various ‘roll your own security’ memes/gifs convince you 🙂

ajs11:04:06

Sounds like client side encryption is not popular, then.

ajs11:04:03

My situation is more complicated than just "use SSL" but I assumed there were some good tools for cross platform client-server encryption, maybe not.

kah0ona11:04:28

I wouldn’t feel comfortable with client side encryption (not being an expert in cryptography)

tatut11:04:38

SSL is the “good cross platform client-server encryption”

kah0ona11:04:50

good luck though 🙂 curious what solution you come up / end up with

kurt-o-sys11:04:19

@ajs what's the use case?

kurt-o-sys11:04:18

(there are some libs doing encryption, but I don't think any of them beats SSL)

ajs11:04:19

@kurt-o-sys its about a non SSL served page that also has a socket to a localhost server. Setting up SSL locally is a bit complex, especially with distribution, I've need reading about that headache all week, so if the hosted page is non SSL that at least allows the connection. Data between the page and local host never leaves the users machine, so perhaps worrying about encryption is not necessary. And the page could still do Ajax over SSL to its remote server. But I though to be safe, encryption to localhost would be wise too.

kurt-o-sys11:04:26

if people are getting into your machine, you have a problem and having your localhost calls encrypted is the last of your concerns, imho.

kurt-o-sys11:04:17

I don't know about your setup, but I let a webserver handle the encryption, I keep internal calls non-encrypted.

kurt-o-sys11:04:23

internal = on the same machine

kurt-o-sys11:04:34

in the same network: webservers handling ssl

ajs11:04:13

I assume that a remote page that communicates with local host never sends data over network? That would make sense. And a non SSL page that hits SSL Ajax URI still encrypts over network?

ajs11:04:40

The page itself is not SSL but all transmissions should still be safe in such a context?

thheller11:04:31

@ajs you can only do client side encryption if you get the "secret" there securely. it is pretty much impossible to do this on the client.

kurt-o-sys11:04:44

a remote page can't communicate with localhost (or well, localhost would be the local machine 🙂 ). A remote page communicates with an 'external' server, and you can setup a webserver (nginx/apache) to connect to, handling ssl. The webserver just dispatches the request to an internal application listening on localhost:xxxx.

ajs11:04:15

A remote page can communicate with a socket hosted on local host. But that wire is still entirely local between the page (in the browser) and local host, the page's remote server is not involved, right?

kurt-o-sys11:04:09

right: if it's all local, no ssl, if it's remote, put a webserver in between handling ssl

thheller11:04:36

the issue with HTTP is that someone can change what the client receives. so if someone were to inject some JS that just replaces the WebSocket class and echos everything to a second server your entire encryption is bypassed.

ajs11:04:35

You mean injecting JS into my remote page so that sends to a different websocket server? Is that a non SSL risk, or also one that can happen on SSL too?

thheller11:04:45

it only matters if the page that loads your JS is insecure. if so other JS can be injected that messes with your security.

thheller11:04:02

if your page is not secure nothing else is going to be secure

thheller11:04:48

SSL ensures that your page is reasonably secure and not messed with

ajs11:04:15

So JS injection is one of the risks specifically associated with non-SSL browser apps? Hadn't considered that, was more thinking just about raw data flow along the wire.

ajs11:04:37

Good point, thanks.

ajs11:04:36

It's very hard to deploy a local app that serves a socket over SSL, because of all the cert issues. I've been reading all the things people do to make that an easy user install, it's quite complicated.

ajs11:04:29

Yes, I've read to their blog posts on this too.

thheller11:04:51

but yeah SSL is a bit annoying to work with

ajs11:04:58

It's not a piece of cake to set that up automatically as part of app installation for any arbitrary user.

ajs11:04:54

Which leaves me with local server serving insecure socket to a remote page, which must then also be insecure as a result, since SSL pages will not connect to insecure sockets

ajs11:04:05

One option I considered is to have the client send stuff first to remote server over SSL which encrypts and sends back. Then client sends to local server, which decrypts.

thheller11:04:27

crypto is really really hard to do correctly and its pretty much impossible if you start within an untrusted insecure context

thheller11:04:56

so back to my initial short answer: use SSL, don't roll your own crypto.

thheller11:04:41

it is painful to work with yes but assuming you are secure when you are not is more painful

ajs11:04:41

Good points, thanks for making them

ajs11:04:27

Just wish there were good out of box tools for easily generating local self signed certs as invisible part of user installation process and getting that setup.

thheller11:04:58

me too 😛

thheller11:04:44

problem really is that everything relies on DNS which you typically don't have for local dev setups

thheller11:04:08

so you'd need to write that first ... its an endless rabbit hole of misery

ajs11:04:04

In reading up in this, it seems that even serving a local socket for development purposes can be risky since it is exposed to any web page running remotely, which if it knows the port you are using, can hit your local socket. Checking request origins doesn't help too much since that can be faked.

ajs12:04:09

So if I write something and run it in my machine and only access it myself via localhost URLs, it is still available to the world

thheller12:04:45

yeah CORS and those things are meant to address that part

thheller12:04:12

which also make development more annoying ...

ajs12:04:24

CORS doesn't help if a web server sends its request as coming from localhost since servers get to send whatever they want for that

ajs12:04:03

Nothing enforces what a server sends as the server in a request

thheller12:04:56

nothing should be able to hit your local socket except your browser. which is secured by CORS. other servers should not be able to access your dev stuff.

thheller12:04:21

but yeah don't expose secrets in dev servers

ajs12:04:15

But if you have your local socket served while you hit a random web site out there, it can access your socket, even if you check its request origin server

ajs12:04:42

Assuming the page is malicious, of course

thheller12:04:16

the webpage can access your server via your browser yes (again CORS)

thheller12:04:21

not via their server

ajs12:04:03

Right, but that means you can't really keep any local websocket server from getting hit when you surf the web

thheller12:04:16

yes you can with CORS ... well sort of ... not 100% that is true.

ajs12:04:47

If I check the server origin before handling socket data, and only allow "http://localhost...", I thought that's not enough because the request can have any server name regardless of what is actually hitting it.

ajs12:04:18

Because CORS does not apply to sockets, only Ajax. So the browser allows it.

thheller12:04:21

yeah you can't really secure a websocket this way. will need to transmit some kind of token that only the "secure" client would know

kzeidler12:04:50

I'm trying to set up re-frame-10x diagnostics on a fresh project, but here's the thing: the "ctrl-H" shortcut to show the tools is hardwired. Unfortunately macOS basically hardwires that combo to "hide window." So I'm at a bit of an impasse https://github.com/Day8/re-frame-10x

kzeidler12:04:58

Any suggestions how to make this work?

danielcompton12:04:49

Ctrl H, not Cmd H

danielcompton12:04:07

Cmd H hides in macOS, 10x uses Ctrl H

kzeidler12:04:16

@danielcompton d'oh, of course. Huh. In that case I guess the shortcut just isn't working for me yet :man-shrugging:

kzeidler12:04:28

Thanks for pointing out my error!

danielcompton12:04:25

Drop by in #re-frame if you can’t figure it out

sekao14:04:49

is there any way to determine if advanced compilations are on? i know about js/COMPILED but that is true when compiling with :simple as well

kzeidler14:04:46

What's the idiomatic way to instantiate a Javascript object that ordinarily gets constructed with 'new'? e.g. "var sphere = new THREE.SphereGeometry(3,3,3);"

borkdude14:04:16

@kzeidler (js/THREE.SphereGeometry. 3 3 3)

pesterhazy15:04:25

@sekao Why would you want to know about that at runtime?

pesterhazy15:04:07

You probably have a good reason, just curious

pesterhazy15:04:31

What I'd do is set some goog.define to different values in the different lein profiles

sekao15:04:18

i'm making two separate versions of paren-soup, one built with :simple and one with :advanced, and i want to make the first one's instarepl just eval directly, and the second one use a web worker for eval. so i need to make a conditional that determines what to do. i figured i could set some flag myself, i was just hoping there was some kind of constant already somewhere

pesterhazy15:04:26

gotcha (don't know of any constant, sorry)

justinlee15:04:35

is there any particular reason to use the dot-form constructor instead of just using new

pesterhazy15:04:40

I think only one, it's nicer

mattly17:04:46

I have a question about npm-deps: If I pull in a library that requires react as a peerDependency, but that’s installed already by f.e. reagent, what’s the best way to resolve the resulting Error: Can't resolve 'react' error?

mattly17:04:31

presumably I’d put react into npm-deps and then set it in :exclusions for reagent

juhoteperi17:04:52

@mattly Reagent doesn't provide npm React so you need to install the npm package yourself (npm-deps or package.json). And excluding the cljsjs package is bad idea, because you will still need the React externs)

juhoteperi17:04:18

And exclusion is not required because npm-deps (node_modules folder) has precedence over foreign-libs from cljsjs packages.

mattly18:04:58

thanks, now I’m on to a nameToPath problem 🙂

puppybits18:04:29

Is there a way to pull in different versions of a lib at runtime? I have a separate cljs project that contains the business logic and would like to be able to pull in older versions so we can dark launch and rollback changes to the business logic.

mattly18:04:48

so, is there an issue with requiring an npm-dep that has a hyphen in its name?

mattly18:04:37

(require [graphql-voyager]) results in an Undefined nameToPath for graphql_voyager error

juhoteperi18:04:52

@mattly Is is possible there is there is some problem with using that package, but it shouldn't be due to the hyphen, react-dom definitely works

mattly18:04:49

I figured it out, it was another missing peerDependency 😕

dpsutton21:04:48

is there a difference between destructuring in a function signature versus in a let statement at the top level of the form? i'm assuming (defn foo [{:keys [ .... gets turned into just a let at the top of the function?

dpsutton21:04:57

performance wise i mean

dnolen22:04:32

no but you really shouldn’t do that in ClojureScript due to how we compile to JavaScript

dnolen22:04:01

you’ll polllute the global environment

dpsutton22:04:48

shouldn't do which? destructure in the function signature?

dnolen22:04:55

oh I misread

dnolen22:04:02

no difference, just do at the function signature

dpsutton22:04:22

cool. thanks