Fork me on GitHub
#shadow-cljs
<
2019-08-21
>
dpsutton00:08:17

@quest in further investigation is CIDER still a possible culprit? I have more time now to investigate with you if you’re still working on it

Quest00:08:01

Don't think so -- happened upon a threadpool exception on one of those runs, so my current theory is that OSX is sometimes nuking the process due for unknown reasons. Appreciate the follow-up though!

dpsutton00:08:33

For sure. Good luck to you and feel free to ping if I can help more

dpsutton00:08:49

Yeah I read through it. I’m a bit confused because there’s no lein involved so I expected the jvm settings from the shadow edn file to work

Quest02:08:45

You're not wrong... no idea why it doesn't. For posterity, this is my shadow-cljs.edn file with the jvm-opts set. It's the vanilla re-frame-template https://github.com/Day8/re-frame-template

superstructor03:08:16

@quest Thanks for using re-frame-template and investigating the cider issue. Do you think the :jvm-opts is something I should add to the +cider profile ? If it reliably solves the issue then at least cider users won't get any bad surprises when using the template ?

Quest05:08:09

@superstructor I'd recommend it... setting :jvm-opts ["-Xmx1G"] seems to reliably fix the issue 100% of the time. If nothing else, might be worth mentioning on the re-frame template README. This issue could be just on OSX though -- I'm not sure about Windows/*nix. Without the option & with the .shadow-cljs cache already present, it seems to pass/fail every other launch

👍 4
thheller06:08:35

as soon as you set :lein true the :jvm-opts have no effect since lein will be starting the JVM.

thheller07:08:07

@quest FWIW I can run with -Xmx16G just fine. it should be dying 100% for you with that right?

thheller07:08:38

you could maybe try running clj -J-Xms16G (note -Xms not -Xmx) which sets the min amount of RAM

thheller07:08:04

so it should in theory die instantly if the OS is killing it just because of RAM?

thheller07:08:59

well maybe not. it just reserves the memory but doesn't actually use it

thheller08:08:25

fun little debug utility I just added to master. finds top level forms generating a big chunk of JS.

thheller08:08:54

(in this case forms above 45000 bytes)

thheller08:08:06

not super useful but interesting to see how much code some forms generate

thheller08:08:08

> Form produced 643580 bytes of JavaScript

mccraigmccraig09:08:02

sounds interesting to me @thheller - output size is a top priority for us atm, and selected info finer-grained than per-namespace sounds useful

thheller09:08:32

I'd stick to build reports for since this number really doesn't mean much.

thheller09:08:01

for example the above generated 643kb is just because it is a macro generating a large (do ...) but all the code is fully removable

thheller09:08:02

but can still be interesting to know. I have done a fair bit of size tuning myself over the years but the build reports have been the only truly useful thing so far

thheller09:08:30

other than digging into the actual sources directly and getting rid of bad concepts that prevented DCE

thheller09:08:42

but for that you kinda need to know how DCE works 😉

mccraigmccraig09:08:51

ah, yeah, if the reported output is all removable, that makes it a less useful metric

thheller09:08:57

worst offender currently is cljs.spec when only used for fspecs and instrument stuff. meaning not actually at runtime in release builds

thheller09:08:07

it still all ends up in the code if you aren't careful

thheller09:08:18

(and npm deps of course) 😉

mccraigmccraig09:08:53

hmm - are there any docs around what being careful constitutes - i'm not at all sure we're not missing some tricks

thheller09:08:17

first of all I'd say: don't worry about it

thheller09:08:13

then look at the build reports. eliminate as many JS deps as you can. then start looking at CLJS code and eliminate the obvious offenders (eg. cljs.pprint)

thheller09:08:38

only dig deeper into namespaces using more than like 100kb or so

thheller09:08:46

unfortunately it isn't possible to tell the actual gzip contribution so there may be code that compresses way better than other code

thheller09:08:08

one common offender for me is reagent due the the amount of keywords it might generated

thheller09:08:44

but it doesn't really make sense to optimize the amount of keywords either

thheller09:08:14

ie. not worth worrying about those bytes since there are bigger fish to fry 😉

mccraigmccraig11:08:01

yeah, we've only got one namespace in the 100kb size range, a couple in the 50kb range, and a lot much smaller - total output size 2.8MB atm. using the build report to figure out how best to modularise seems like the biggest win for us atm

metehan12:08:46

when I run shadow cljs I run this command too sass --watch web/scss/spill/spill.scss web/root/css/app.css to get my sass compiled. Is there any way to run this with shadow?

thheller12:08:23

not currently but maybe soon 😉

metehan13:08:38

cool, btw shadow is great since yesterday I was playing with it. thanks for making this 🙂

defa14:08:45

I’m trying to set up a project with a pedestal backend and re-frame frontend using clj/deps.edn and shadow-cljs but I can not figure out how to put things together. How to I configure the pedestal backend to be used by shadow-js or am I getting something completely wrong?

thheller14:08:36

shadow-cljs just output files and your pedestal backend should serve them

thheller14:08:49

thats as far as the connection goes. pedestal doesn't need to know anything about shadow-cljs

thheller14:08:04

in your pedestal service conf you can set ::http/file-path "public"

thheller14:08:24

and have shadow-cljs output to public/js (does so by default)

thheller14:08:50

which you then access via (or whatever your module name was)

defa14:08:43

… in the :devtools section of shadow-cljs.edn.

thheller14:08:57

dunno why that is in the that template but it is not used if you use your own pedestal backend

thheller14:08:48

@superstructor the config generated by the template is unnecessarily complex and could be modernized a bit

thheller14:08:40

it generated this

{:lein   true

 :nrepl {:port 8777}

 :builds {:app {:target          :browser
                :output-dir      "resources/public/js/compiled"
                :asset-path      "/js/compiled"
                :dev             {:modules          {:app {:entries [devtools.preload
                                                                     day8.re-frame-10x.preload
                                                                     dummy-10x.core]}}
                                  :compiler-options {:closure-defines {re-frame.trace.trace-enabled?        true
                                                                       day8.re-frame.tracing.trace-enabled? true}}}
                :release         {:modules          {:app {:entries [dummy-10x.core]}}
                                  :compiler-options {:optimizations :advanced
                                                     :pretty-print  false
                                                     :closure-defines {goog.DEBUG                           false
                                                                       re-frame.trace.trace-enabled?        false
                                                                       day8.re-frame.tracing.trace-enabled? false}}}
                :devtools        {:http-root    "resources/public"
                                  :http-port    8280
                                  :preloads     [devtools.preload
                                                 day8.re-frame-10x.preload]
                                  :after-load   dummy-10x.core/mount-root}}}}

thheller14:08:56

and could be this

{:lein true

 :nrepl {:port 8777}

 :dev-http {8280 "resources/public"}

 :builds {:app {:target :browser
                :output-dir "resources/public/js/compiled"
                :asset-path "/js/compiled"
                :modules {:app {:init-fn dummy-10x.core/init
                                :preloads [devtools.preload
                                           day8.re-frame-10x.preload]}}
                :dev {:closure-defines {re-frame.trace.trace-enabled? true
                                        day8.re-frame.tracing.trace-enabled? true}}}}}

thheller14:08:31

I'll see if I can throw together a PR

defa14:08:17

@thheller thanks! so there are two http-servers running: pedestal and the one that is started by shadow-cljs.

thheller14:08:45

you don't need the one started by shadow-cljs if you have your own backend

defa14:08:23

Guess I have messed up my project somehow… will start with a clean slate and read the docu again.

thheller14:08:40

there isn't much to it. if you share some config I can probably tell you where you went wrong.

defa15:08:16

thanks in advance, here is my config: https://pastebin.com/dtSykUxd

thheller15:08:09

:npm-deps   [
                                   {:keycloak-js "^6.0.1"}
                                   ]
this is invalid and doesn't do anything

thheller15:08:29

your pedestal setup is missing

thheller15:08:48

mainly your service config

thheller15:08:12

ok so the server is configured to run at 8080 and serving the resources/public dir

thheller15:08:30

so everything should be working fine if you open http://localhost:8080

defa15:08:54

I got it to the point where everything seems to work but the automatic reload. I get the HUD showing up and telling me view.cljs has been reloaded but the page does not update.

thheller15:08:26

right you removed the hook config

thheller15:08:45

open the telifit-web/core.cljs

thheller15:08:08

and change (defn mount-root [] to (defn ^:dev/after-load mount-root []

thheller15:08:18

this will well shadow-cljs to call that function after it has reloaded code

thheller15:08:26

and that fn will re-render your ui

defa15:08:51

Thanks a lot 🙂 … it is working now. Will also have a look at your response to @superstructor regarding the unnecessarily complex shadow-cljs.edn

thheller15:08:07

{:deps {:aliases [:cljs]}
 :source-paths ["src/cljs"]
 :builds {:app {:target :browser
                :output-dir "resources/public/js/compiled"
                :asset-path "/js/compiled"
                :modules {:app {:entries [telifit-web.core]
                                :preloads [devtools.preload
                                           day8.re-frame-10x.preload
                                           re-frisk.preload]}}
                :dev {:compiler-options {:closure-defines {re-frame.trace.trace-enabled? true
                                                           day8.re-frame.tracing.trace-enabled? true}}}
                }}}

defa15:08:09

I had a look at you pull request for the template and applied the changes to my code.

defa15:08:01

Thank you very much for your support. Not only shadow-cljs is impressive but also your support to the community in general!

Quest18:08:10

*Edit: found the known issue affecting CIDER pprinting https://github.com/thheller/shadow-cljs/issues/510

Quest18:08:42

From thheller's response it sounds like something is stripping newlines between the browser -> Emacs REPL output. I get a single line of EDN output on my setup

superstructor18:08:01

Thanks for the review and PR @thheller Much appreciated! I have merged and will release shortly.

jpmonettas19:08:50

hi! what can I use so a namespace gets reloaded but def with atoms aren't redefined? defonce doesn't seem to work for me

leontalbot19:08:05

Hi! I am injecting on any live site (with a chrome extension) my app js (js/main.js) produced by shadow-cljs

leontalbot19:08:46

I am getting 404 errors when page tries to load “https://www.a-live-site.com/js/cljs-runtime/…”

leontalbot19:08:17

I would want the page to look for “http://localhost:3000/js/cljs-runtime/…”

leontalbot19:08:41

Is there a way to do that?

leontalbot19:08:04

I suppose this is obvious, but can’t find out

leontalbot19:08:38

I was able to serve a release build, but not ideal when I want a reload workflow for development

superstructor19:08:20

Done and released. Thanks 🙂

👏 4
👍 4
superstructor19:08:09

Released @thheller's improvements to the template. Thanks 🙂

mss20:08:22

hey all, have a kind of funky situation where I’m targeting an electron browser window with node integration enabled but loading my js via a script tag. I’d like to load it via the script tag as opposed to bundling the file with my electron distribution so code updates are automatic and don’t require an app update. setting my target to :browser w/ the associated config options leads to my getting weird errors like The required JS dependency "path" is not available... despite path being installed and available in the correct dir. setting the target to :node-script appends an #!/usr/bin/env node to the output file, which doesn’t actually work in a browser context when loaded via a script tag. anyone have an idea for either 1) how to specify that node requires are kosher in a :browser target or 2) strip the #!/usr/bin/env node heading from the output file in a :node-script target?

thheller20:08:27

@superstructor cool. can you tell me how to test that template locally? I always forget 😛

thheller20:08:46

if you want REPL pprint you can set :devtools {:repl-pprint true}

thheller20:08:11

but cider seems to expect some of its own stuff to do the pprint and I have no clue how that side works

Quest20:08:01

I don't blame you, went digging through the code this morning and had a rough time of it. I added what little I could figure out at https://github.com/thheller/shadow-cljs/issues/510#issuecomment-523633532

thheller20:08:56

@leontalbot there is support for building chrome extensions directly. did you use that or did you use :browser? https://github.com/thheller/shadow-cljs/issues/279

thheller20:08:46

@mss :node-script is for node scripts. it is not intended to run in the browser. you can use the regular :target :browser and set :js-options {:js-provider :require}

🙌 4
thheller20:08:52

defonce is exactly for that case. dunno why it wouldn't work though? what is your build setup?

leontalbot20:08:05

I used Tampermonkey + :browser

leontalbot20:08:06

interesting, so that could fix the wrong cljs-runtime urls app needs to get?

thheller20:08:10

you can control which URL it is trying to connect to via :devtools-url https://shadow-cljs.github.io/docs/UsersGuide.html#proxy-support

thheller20:08:34

or just :asset-path "..."

thheller20:08:51

but the whole things isn't really designed to be injected into arbitrary pages

thheller20:08:13

and can very easily break

leontalbot21:08:16

:asset-path works, then getting CORS error

thheller21:08:20

you might get a bit further by setting :devtools {:loader-mode :eval}

thheller21:08:44

but yeah injecting a dev build is gonna break in various ways

jpmonettas21:08:27

this is my shadow-cljs.edn

{:source-paths ["src/cljs"]
 :dependencies [[day8.re-frame/http-fx "0.1.6"]
                [dorothy "0.0.7"]
                [reagent "0.8.1"]
                [re-frame "0.10.8"]
                [datascript "0.17.1"]
                [re-com "2.5.0"]]
 :dev-http {9500 "resources/public/"}
 :builds {:app {:output-dir "resources/public/js/"
                :asset-path "/js"
                :target :browser
                :compiler-options {:output-feature-set :es6}
                :modules {:main {:init-fn clograms.core/init}}
                :devtools {:after-load clograms.core/mount-root}}}}

jpmonettas21:08:00

if I add ^:dev/once to the ns that has the atom then everything is fine (but I can't reload code there)

thheller21:08:25

uhm defonce is an actual (defonce the-atom (atom {})?

jpmonettas21:08:37

it is exactly that

jpmonettas21:08:47

(defonce storm (atom {}))

thheller21:08:41

ok that shouldn't be reassigned then? unless you are manually calling (reset! storm {}) or something?

thheller21:08:09

you can verify that it is only set once by doing (defonce storm (do (prn :init-the-atom) (atom {}))

👍 4
jpmonettas21:08:38

yeah I'm seeing the :init-the-atom again when reloading

thheller21:08:38

thats odd. is the name maybe conflicting with something?

jpmonettas21:08:14

wow you are right, I have an alias with the same name facepalm

thheller21:08:32

ns alias? that doesn't matter

jpmonettas21:08:07

yeah ns alias

jpmonettas21:08:42

well, that did the trick

jpmonettas21:08:58

I renamed the atom to storm-atom and now I only see the :init-the-atom once

thheller21:08:15

and what was the ns alias?

jpmonettas21:08:36

(:require ["@projectstorm/react-diagrams" :as storm])

thheller21:08:09

ah ok its a JS alias. I guess that might confuse things

jpmonettas21:08:41

now it works, thanks again!

superstructor22:08:39

Yeah its a bit magic. Anytime you run the lein new re-frame... command within the re-frame-template project dir lein will use that copy and not look for the jar.

Quest23:08:44
replied to a thread:

@thheller just setting :devtools {:repl-pprint true} got it working in CIDER! Thank you & documented this at https://github.com/thheller/shadow-cljs/wiki/Cider

👍 4
leontalbot01:08:20

well, :loader-mode :eval works! thanks! only thing is I see “connection fail” bottom left warning on ui

thheller07:08:16

that is controlled by :devtools {:devtools-url ""} since that by default will try to use the current document.location