Fork me on GitHub
#shadow-cljs
<
2019-10-14
>
thheller08:10:54

@bbss that kinda looks like you have a dependency conflict somewhere? which shadow-cljs version is this? looks like it might be kinda old?

bbss08:10:31

I just updated the shadow-cljs to latest git version afaict, maybe it's a conflict, but this does run compile with lein +cljs profile.

bbss08:10:33

ah, scratch that, not latest version

thheller08:10:39

uhm you upgraded to the latest git?

bbss08:10:46

updated but seems not on path

bbss08:10:57

sorry.. checking with newest

thheller08:10:26

don't use a git checkout of shadow-cljs

thheller08:10:36

especially not with deps.edn :local/root

thheller08:10:57

it is not compatible. it does require compiling a few extra files which deps.edn doesn't support

thheller08:10:15

there are some .java files that need to be compiled, which lein does but deps.edn doesn't

thheller08:10:48

so that would explain why it works with lein maybe?

thheller08:10:19

that NPE however was caused a while back when an incompatible CLJS version was used

thheller08:10:50

but you seem to have the correct CLJS version, so it probably just is an old shadow-cljs version? can't see which version that is. doesn't appear to be the latest since the souce doesn't match (ie. compiler.clj:881 isn't par-compile-cljs-sources)

bbss08:10:02

I was on 2.8.18, now updated to 2.8.64.

bbss08:10:47

Getting

"Execution error (FileNotFoundException) at clojure.main/main (main.java:40).\nCould not locate shadow/cljs/devtools/cli__init.class, shadow/cljs/devtools/cli.clj or shadow/cljs/devtools/cli.cljc on classpath.\n"

thheller08:10:48

looks like a classpath issue to me?

bbss08:10:57

alright, adding shadow-cljs to deps.edn gets me further

ts150308:10:07

Hello guys. I’ve started a new project with shadow-cljs and I’m trying to integrate shadow-cljs with leiningen, but getting this warning at the compile-time and it brakes the hot reload

shadow-cljs - running: lein with-profile +cljs run -m shadow.cljs.devtools.cli --npm watch app
[2019-10-14 11:03:20.312 - WARNING] provide conflict for #{minorodata.app.subs} provided by cljs/minorodata/app/subs.cljs and {"/minorodata/app/subs.cljs" #{minorodata.app.subs}}
[2019-10-14 11:03:20.314 - WARNING] provide conflict for #{minorodata.app.db} provided by cljs/minorodata/app/db.cljs and {"/minorodata/app/db.cljs" #{minorodata.app.db}}
[2019-10-14 11:03:20.314 - WARNING] provide conflict for #{minorodata.app.events} provided by cljs/minorodata/app/events.cljs and {"/minorodata/app/events.cljs" #{minorodata.app.events}}
[2019-10-14 11:03:20.315 - WARNING] provide conflict for #{minorodata.app.router} provided by cljs/minorodata/app/router.cljs and {"/minorodata/app/router.cljs" #{minorodata.app.router}}
[2019-10-14 11:03:20.315 - WARNING] provide conflict for #{minorodata.core} provided by cljs/minorodata/core.cljs and {"/minorodata/core.cljs" #{minorodata.core}}

thheller08:10:04

@sergey.tkachenko looks like you might have you :source-paths configured badly? maybe :source-paths ["src" "src/cljs"]?

ts150308:10:34

my lein config

ts150308:10:20

and I’ve added {:lein {:profile "+cljs"} in the shadow-cljs.edn

ts150308:10:35

all listed files in the warnings lives in the src/cljs folder

thheller08:10:47

and do you have an extra :source-paths outside :profiles? otherwise I believe it defaults to :source-paths ["src"]?

ts150308:10:48

@thheller no I don’t have extra source-paths

thheller08:10:44

then add an extra :source-paths []. or :source-paths ["src/clj" "src/cljc"]

thheller08:10:52

pretty sure it otherwise defaults to adding src

bbss08:10:05

I'm extending some es6 classes that's now giving me trouble:

[:main] Compiling ...
[:main] Build failure:
Closure compilation failed with 10 errors
--- main/gsv/ui/HighPitchMapController.js:1
Requested module does not have an export "clamp".
--- main/gsv/ui/HighPitchMapController.js:2
Requested module does not have an export "Controller".
--- main/gsv/ui/HighPitchMapController.js:3
Requested module does not have an export "WebMercatorViewport".
--- main/gsv/ui/HighPitchMapController.js:3
Requested module does not have an export "normalizeViewportProps".
--- main/gsv/ui/HighPitchMapController.js:4
Requested module does not have an export "LinearInterpolator".
--- remaining errors ommitted ...

thheller08:10:48

so you were on a rather old version previously?

bbss08:10:06

Yes, 2.8.18

bbss08:10:12

But this still works with lein

bbss08:10:21

Any way I should probably fix those issues..

thheller08:10:42

you are in charge of your dependencies if you use lein or deps.edn

thheller08:10:57

therefore you must resolve conflicts. deps resolves conflicts differently than lein does

bbss08:10:09

ah, that makes sense. Thanks 🙂

thheller08:10:30

so check how they resolved and sort out the differences. most likely a different closure-compiler verison being used

ts150308:10:55

@thheller :source-paths [] fixed the problem )) Thanks :thumbsup:

👍 4
thheller08:10:04

you seem to be using import { Controller } from "something" maybe?

thheller08:10:57

so the issue with JS interop currently is that the closure compiler ONLY accepts "strict" interop

thheller08:10:19

which means import { Controller } only works if the "something" was actual ESM code

thheller08:10:40

BUT since we are treating node_modules code differently it never is actual ESM code

thheller08:10:03

for a while the closure compiler (like webpack) allowed a non-strict variant where this still worked

thheller08:10:28

so the only way to do this now would be import X from "something" and then X.Controller

thheller08:10:55

it is a bit annoying that it works that way but we are kinda at the mercy of the closure compiler

thheller08:10:12

but webpack is going to be strict-only with v5 also so that'll make things "better" I hope

thheller08:10:11

I presume that you just had an older version due to lein dependency rules?

bbss08:10:23

Okay, this is useful information for me, I am looking to extend that library from cljs, and was kinda hoping I could just magically use shadow-cljs. But in case that won't work out I'll need to understand more about the module importing. So far usually I can get by with js-options resolve.

bbss08:10:30

Might be..

thheller08:10:19

you can use it. just need to adjust your import statements.

thheller08:10:10

the whole CommonJS<->ESM interop story in the JS world is a complete mess

thheller08:10:24

would have been better if they didn't even start with ESM in the first place

thheller08:10:20

now it is a breaking change for most JS code out there since babel/webpack at first added a "compatibility" mode that can't actually work if you follow the spec

bbss09:10:53

getting a lot more warnings, but it compiles! Thanks!

thheller09:10:56

can you tell me why you are trying to use a git checkout of shadow-cljs in the first place?

bbss09:10:28

I always feel a bit scared when adding an npm dependency, so I hope they figure out something out wrt a spec that will work for everyone, also still having weird issues with aws-amplify for example, thankfully after digging around their code-base and trying several js-options resolve things that worked out eventually.

thheller09:10:57

what :resolve are you messing with?

thheller09:10:29

it should never be necessary to adjust :resolve for node_modules packages?

bbss09:10:34

A while back (months) I needed a fix you had just pushed so that's why I tried to build from a fresh git pull.

bbss09:10:09

Ah well it's a :browser build. but I needed

:js-options {:resolve {"util" {:target :npm
                                                :require "./util"}
                                        "querystring" {:target :npm
                                                       :require "query-string"}}}

thheller09:10:25

don't need those

thheller09:10:49

if you do need those then you don't have shadow-cljs installed in the project

thheller09:10:55

which I should really make a hard error again

thheller09:10:36

you need to install npm install shadow-cljs in your project so that it brings in the node-libs-browser package. which provides browser polyfills for util as well as querystring

thheller09:10:50

(which are otherwise node built-in packages that don't run in the browser)

bbss09:10:06

I think that was what "fixed" it at the time. But admittedly I just use amplify publish for pushing my front-end now, and haven't wanted to touch that code for updating. Ah, that makes sense! I'll try that 🙂

thheller09:10:15

if installing shadow-cljs in the project doesn't fix it then you may just have a dependency conflict on the npm side

thheller09:10:27

I wish things were easier .. believe me 😛

bbss09:10:30

I can imagine, shadow-cljs is great though!

credulous12:10:58

Hi! I’m a member of that crowd who loves clojure/script, but has struggled with tooling every time I’ve tried to start a project. I’m going to try again! With shadow-cljs of course.

credulous12:10:13

So: hoping for some views on current best practices on a couple issues:

credulous12:10:41

1) Is there any reason to configure a project as full stack (server + client in one project) versus having two distinct projects? and

credulous12:10:53

2) Is there any particular reason beyond personal taste to use clojure on the server versus using nodejs? I never considered nodejs as a possibility until I started reading shadow-cljs docs, but the unanswered question for me are the advantages to that approach.

thheller12:10:59

@credulous if you want to share code between client/server it can make it easier if you just have one project. still can use 2 different tools though, lein for CLJ and shadow-cljs for CLJS for example

thheller12:10:21

2) I would never personally write anything in node.js if using clojure is also an option

thheller12:10:49

node is just a horrible platform to build one, clojure on the JVM is soooo much better it doesn't even compare 😛

credulous13:10:02

OK! Enough of the shadow-cljs docs are given over to nodejs integration that I wondered if I was missing out on something.

thheller13:10:23

the difference is really in node vs the JVM

credulous13:10:56

Very helpful, thanks. I think I’ll do two projects because in retrospect a lot of my difficulties have been in having two repls going in one editor, etc. and I’ve never been that bothered by code sharing between server and client.

credulous13:10:05

And I’ll use lein for the server. Awesome, thanks

isak14:10:47

@sandbags If you post your question here, I'm sure someone can help you. What is the syntax you are trying to use for js?

sandbags14:10:45

Okay it looks like I may have answered my own problem in trying to write it up. However it throws up a question, what worked for including a 3rd party JS file was (:require ["jstest" :as jstest]) however none of js/jstest, src/js/jstest or /src/js/jstest with or without a ".js" extension worked. From my reading of the docs I thought it should be prefixed by 'src/js/` as this is the folder the .js file is in within my project. If anyone can tell me what I missed I'd be grateful. Thanks (and thanks @isak for suggesting i post here because I had to re-try several things to write up what I had done so far and then thought to try with no path!)

4
sandbags14:10:46

Actually I say it worked, the lein dev compilation phase is not erroring out anymore about the dependency, Cursive is still not resolving it. But maybe it can't from where it lives. Yep, I can find my code in the app.js file. Looks good from here.

jherrlin16:10:02

Hey! I have problem with what I think is the combination of shadow-cljs and ptaoussanis's Sente. Using re-frames lein template to generate a new project with: lein new re-frame re-learn +10x +cider +handler +re-com. Have a minimal app where I want to send a message back and forth between client and server. But i get failed: Error during WebSocket handshake: Unexpected response code: 500 and ERROR [taoensso.sente:1058] - WebSocket error: [object Event] all the time. Have used Sente with lein and figwheel before without any hassle. Anyone got an idea?

thheller16:10:15

@sandbags not exactly sure what your question is. there are two different kinds of ways shadow-cljs can include JS. there is npm and then there is the classpath. in case of the classpath prefixing with src/js is exactly the wrong thing to do. I tried explaining the classpath https://shadow-cljs.github.io/docs/UsersGuide.html#_the_classpath and https://shadow-cljs.github.io/docs/UsersGuide.html#classpath-js

thheller16:10:45

in short if you have a src/js/jstest.js file then :source-paths needs to include src/js and you include the file via /jstest.js

thheller16:10:56

@jherrlin do you connect to the correct websocket server? and what does your "handler" look like?

thheller16:10:02

if I run the command you posted a src/clj/re_learn/server.clj is created

thheller16:10:11

do you actually run and connect to that server?

jherrlin18:10:20

@thheller The handler looks like this:

(def dev-handler (-> #'routes
                     wrap-reload
                     ring.middleware.keyword-params/wrap-keyword-params
                     ring.middleware.params/wrap-params
                     (ring.middleware.defaults/wrap-defaults
                      ring.middleware.defaults/site-defaults)
                     ))
It looks to me like the ws request is to the correct host and port.

jherrlin18:10:08

The project in all its glory is here: https://github.com/jherrlin/sente-example

thheller18:10:12

the generated template starts the server on :3000 so it looks like :8280 is the shadow-cljs http server?

thheller18:10:38

yeah don't use the shadow-cljs server

thheller18:10:51

it is likely that sente doesn't support that

jherrlin18:10:06

okey, make sense

thheller18:10:24

just run lein run -m shadow-sente.server separately

thheller18:10:43

sente might only support http-kit I'm not sure

jherrlin18:10:43

okey, ill try that

thheller18:10:47

shadow-cljs doesn't use http-kit

jherrlin18:10:50

then http-kit will kick in_

thheller18:10:06

looks like it yes

jherrlin18:10:15

yeah, sente needs the http-kit here

jherrlin18:10:45

thank you soo much for your help!

thheller18:10:56

https://github.com/ptaoussanis/sente#getting-started seems like it might support other servers as well

thheller18:10:39

but yeah just run it separately. it is safer that way

jherrlin18:10:40

yeah, it got for some other servers to, but i have used http-kit before and that worked good

thheller18:10:01

you are not going to run this through shadow-cljs in production anyways

thheller18:10:07

so best to keep it separate from the beginning

jherrlin18:10:50

so happy for your help, will try to work it out!

jherrlin19:10:13

got it working ❤️

jherrlin16:10:18

@thheller had to leave the computer. Will respond when I am back. Thanks for responding!

sathya17:10:54

Hi guys, I ran into this issue when running shadow-cljs watch app ? This seems to be caused by code signing requirement enforced by OSX catalina (root cause seems to be the dynamically loaded https://github.com/gjoseph/BarbaryWatchService). I suspect this might cause issues with figwheel as well.

Exception in thread "main" java.lang.UnsatisfiedLinkError: /private/var/folders/r3/hf3d1qyj6d707240ymkh2yx40000gn/T/jna7357045320253869696.tmp: dlopen(/private/var/folders/r3/hf3d1qyj6d707240ymkh2yx40000gn/T/jna7357045320253869696.tmp, 1): no suitable image found.  Did find:
	/private/var/folders/r3/hf3d1qyj6d707240ymkh2yx40000gn/T/jna7357045320253869696.tmp: code signature in (/private/var/folders/r3/hf3d1qyj6d707240ymkh2yx40000gn/T/jna7357045320253869696.tmp) not valid for use in process using Library Validation: mapped file has no cdhash, completely unsigned? Code has to be at least ad-hoc signed.
Has anyone faced the same issue ?

thheller17:10:16

@sathya no clue what that is. you can turn off using that watcher via :fs-watch {:hawk false}. It'll use the default JVM watcher then

thheller17:10:14

seems like that might be a problem for all catalina installs. hawk or the underlying BarbaryWatchService is only used on macOS because the default JVM file watch is kinda slow and has a 2sec delay which bothered people

sathya17:10:21

aha, thanks for the quick response. I will give that a go now.

sathya17:10:21

great, thanks. I think i have to make do with the polling watcher for now (great perk for upgrading this soon ;)). I figured the config actually needs to be :fs-watch {:watcher :polling}.

thheller17:10:58

:fs-watch {:hawk false} didn't work?

lilactown17:10:56

:thinking_face: i’m about to upgrade to catalina. hopefully this doesn’t hit hot reload perf too bad

thheller17:10:19

:polling is basically telling hawk to use the JVM watcher ... which is kinda the same as not using hawk in the first place

thheller17:10:34

catalina seems to break a lot of stuff

thheller17:10:44

twitter is full of upgrade horrors 😛

sathya18:10:40

> :fs-watch {:hawk false} didn't work? Just realised that I had downgraded to shadow-cljs 2.6.0 to test something. :fs-watch {:hawk false} works with 2.8.64, but not with 2.6.0 :fs-watch {:watcher :polling} works with both versions 🙂

thheller18:10:42

ok yeah probably added that after 2.6.0

sandbags18:10:39

@thheller hrmm… this is puzzling. I assume by :source-paths you are talking about project.clj rather than shadow-cljs.edn. My :source-paths doesn't include src/js, only src/clj and src/cljs, perhaps I missed an instruction or implied good practice there. However I can reference the files using :js-options :resolve and (:require ["foo" :as foo]) (where my JS file is src/js/foo.js). From what you are saying it seems what I've done shouldn't work, or is only working accidentally perhaps.

thheller18:10:04

@sandbags that is the point. you need to include it in your :source-paths

sandbags18:10:09

It's been a long time since i did any CLJS and the last time was using Figwheel so I am trying to catch up with all the changes

thheller18:10:20

learn what the classpath means

thheller18:10:40

really that is the concept you need to understand for this to make any sense at all

thheller18:10:53

do not mess with :js-options, that is wrong for what you are trying to do

sandbags18:10:59

yeah i'll read your link, thanks

sandbags19:10:32

Okay so I did read this before, but perhaps not as closely. I have amended my shadow-cljs.edn as you indicated, removing js-options and adding a source-paths including ['src/js'] (I think my confusion here was that using the re-frame template doesn't include source-paths). However every variant of the :require statement I tried ("/jstest", "/jstest.js", "jstest", "jstest.js") gets "The required JS dependency "jstest" is not available". The file in question is src/js/jstest.js.

thheller19:10:02

so then you missed another important section

thheller19:10:26

you are using :lein true or some form of :lein in shadow-cljs.edn yes?

sandbags19:10:48

Ack… i hadn't noticed that at the top.

thheller19:10:52

then :source-paths in shadow-cljs.edn have no effect whatsoever. lein is in charge of managing them, so you need to adjust it there

sandbags19:10:55

So it's pulling them from project.clj

sandbags19:10:13

except, i had added it so the :source-paths in project.clj already

sandbags19:10:38

just messing around to see what i might be missing

thheller19:10:54

so what did you add? :source-paths ["src/clj" "src/js" ...]?

thheller19:10:04

and where is your actual file?

sandbags19:10:14

in project.clj: :source-paths ["src/clj" "src/cljs" "src/js"] the file is src/js/jstest.js

sandbags19:10:43

(I'm using the re-frame template if that helps)

thheller19:10:49

did you restart after adjusting the :source-paths?

thheller19:10:05

changing :source-paths and :dependencies requires a full restart of shadow-cljs

sandbags19:10:27

but i'll do it again to be sure

thheller19:10:34

so then (:require ["/jstest.js" :as x]) should do it (with no additional config in :js-options at all)

sandbags19:10:48

Ah, yes the "/" is important

thheller19:10:55

yes, very important

sandbags19:10:57

okay I think i have it now, thanks

sandbags19:10:10

(i had but had been messing about with variants so didn't have the "/" at the beginning any more)

sandbags19:10:17

I appreciate the help, thank you.

thheller19:10:25

otherwise the rules kick in and it'll try to look up in node_modules

thheller20:10:16

@sathya anything noticeably different after disabling :hawk?

mateusz-fiolka20:10:10

Hi. As I understand I can use :handler inside of dev-http to provide my own request handling. Is there a way for me to add some jvm deps that I could use inside of the handler?

mateusz-fiolka20:10:15

Ah, ok I've found :deps

thheller20:10:24

just add regular :dependencies or :deps in case you are using deps.edn

thheller20:10:55

but seriously consider running your http server separately (without shadow-cljs)

thheller20:10:08

your production setup won't run inside shadow-cljs either so your dev stuff shouldn't either

thheller20:10:33

keep things as similar as possible otherwise it'll just end in headaches

mateusz-fiolka20:10:35

This is private app running on my local machine

mateusz-fiolka20:10:08

So shadowcljs will be running on production 🙂

mateusz-fiolka20:10:49

And the server part will be fairly minimal and stable

lilactown21:10:49

I’m getting a strange error under advanced optimizations that’s fixed when I enable pretty-print and psuedo-names

thheller21:10:26

externs, likely js->clj if you use that

thheller21:10:49

could also be another conflict with in case you are using other JS on the page or creating globals manually

lilactown21:10:50

it only came about when I code split the app into two bundles

thheller21:10:17

ok then you have a conflict with a global on the page

thheller21:10:34

you can likely fix it if you just set :output-wrapper true

thheller21:10:42

that only defaults to true when using one module

thheller21:10:55

say you have google analytics on the page

thheller21:10:24

if you don't have externs for that than its ga global will clash with one of the variables the CLJS outputs creates

thheller21:10:06

:output-wrapper is the easy quick fix

thheller21:10:24

but makes your output larger by a small percentage so its usually ok

lilactown21:10:27

that’s in :compiler-options?

thheller21:10:51

yes, correct

thheller21:10:24

I should probably make it the default always and let people disable it in case they want to optimize

lilactown21:10:02

yep, that fixed it

lilactown21:10:22

thanks for the help thheller! 😄

isak22:10:49

i ran into this too 🙂

lilactown23:10:24

hrm another weird error related to the output wrapper, now that it’s on:

core.cljs:111 Uncaught ReferenceError: $APP is not defined

lilactown23:10:13

weird is that I cannot reproduce this locally

lilactown23:10:02

race condition because I’m trying to append dependent scripts to the page

thheller09:10:03

yeah things must be loaded in order. it is recommended to use the module loader for more complex scenarios.