Fork me on GitHub
#shadow-cljs
<
2017-12-21
>
seako02:12:48

@thheller i'd like to help with the documentation writing effort, how can i get started?

seako02:12:44

by which i mean, are there things in particular that you'd like documented but never have the time to document?

Jon02:12:09

I want h2 too..

Jon03:12:40

Is there docs for using shadow-cljs in clj now?

Jon03:12:50

I got errors in my attempts

Jon03:12:55

Exception in thread "main" clojure.lang.ExceptionInfo: missing instance {}
	at clojure.core$ex_info.invokeStatic(core.clj:4739)
	at clojure.core$ex_info.invoke(core.clj:4739)
	at shadow.cljs.devtools.server.runtime$get_instance_BANG_.invokeStatic(runtime.clj:11)
	at shadow.cljs.devtools.server.runtime$get_instance_BANG_.invoke(runtime.clj:8)
	at shadow.cljs.devtools.api$get_or_start_worker.invokeStatic(api.clj:104)
	at shadow.cljs.devtools.api$get_or_start_worker.invoke(api.clj:99)
	at shadow.cljs.devtools.api$watch.invokeStatic(api.clj:125)
	at shadow.cljs.devtools.api$watch.invoke(api.clj:111)
	at shadow.cljs.devtools.api$watch.invokeStatic(api.clj:115)
	at shadow.cljs.devtools.api$watch.invoke(api.clj:111)
	at build.watch$_main.invokeStatic(watch.clj:12)
	at build.watch$_main.invoke(watch.clj:8)
	at clojure.lang.AFn.applyToHelper(AFn.java:152)
	at clojure.lang.AFn.applyTo(AFn.java:144)
	at clojure.lang.Var.applyTo(Var.java:702)
	at clojure.core$apply.invokeStatic(core.clj:657)
	at clojure.main$main_opt.invokeStatic(main.clj:317)
	at clojure.main$main_opt.invoke(main.clj:313)
	at clojure.main$main.invokeStatic(main.clj:424)
	at clojure.main$main.doInvoke(main.clj:387)
	at clojure.lang.RestFn.applyTo(RestFn.java:137)
	at clojure.lang.Var.applyTo(Var.java:702)
	at clojure.main.main(main.java:37)

thheller07:12:32

@seako cool! I want to document all the things. I never know what to document since I wrote the thing and know how everything works. Anything helps really.

thheller07:12:32

@jiyinyiyong in clj call (api/with-runtime (api/watch ...)) if you want a short lived runtime. (shadow.cljs.devtools.server/start!) if you want to start and leave it running in the background.

Jon11:12:19

2 | (ns app.updater (:require [respo.cursor :refer [mutate]]))
   3 |
   4 | (defn updater [store op op-data]
   5 |   (case op
---------^----------------------------------------------------------------------
 Cannot infer target type in expression (. G__35616 -fqn)
--------------------------------------------------------------------------------
   6 |     :states (update store :states (mutate op-data))
   7 |     :content (assoc store :content op-data)
   8 |     store))

Jon11:12:38

didn't see this warning before, what does it mean?

Jon11:12:10

=>> clj -m build.compile
Exception in thread "main" java.lang.AssertionError: Assert failed: (map? http)
	at shadow.cljs.devtools.server.worker$start.invokeStatic(worker.clj:106)
	at shadow.cljs.devtools.server.worker$start.invoke(worker.clj:106)
	at shadow.cljs.devtools.server.supervisor$start_worker.invokeStatic(supervisor.clj:30)
	at shadow.cljs.devtools.server.supervisor$start_worker.invoke(supervisor.clj:23)
	at shadow.cljs.devtools.api$get_or_start_worker.invokeStatic(api.clj:108)
	at shadow.cljs.devtools.api$get_or_start_worker.invoke(api.clj:99)
	at shadow.cljs.devtools.api$watch.invokeStatic(api.clj:125)
	at shadow.cljs.devtools.api$watch.invoke(api.clj:111)
	at shadow.cljs.devtools.api$watch.invokeStatic(api.clj:115)
	at shadow.cljs.devtools.api$watch.invoke(api.clj:111)
	at build.compile$_main$body_fn__29460__auto____31659.invoke(compile.clj:9)
	at build.compile$_main.invokeStatic(compile.clj:8)
	at build.compile$_main.invoke(compile.clj:7)
	at clojure.lang.AFn.applyToHelper(AFn.java:152)
	at clojure.lang.AFn.applyTo(AFn.java:144)
	at clojure.lang.Var.applyTo(Var.java:702)
	at clojure.core$apply.invokeStatic(core.clj:657)
	at clojure.main$main_opt.invokeStatic(main.clj:317)
	at clojure.main$main_opt.invoke(main.clj:313)
	at clojure.main$main.invokeStatic(main.clj:424)
	at clojure.main$main.doInvoke(main.clj:387)
	at clojure.lang.RestFn.applyTo(RestFn.java:137)
	at clojure.lang.Var.applyTo(Var.java:702)
	at clojure.main.main(main.java:37)

Jon11:12:18

(ns build.compile
  (:require [shadow.cljs.devtools.api :as api]
            [shadow.cljs.devtools.server :as server]
            [clojure.java.shell :refer [sh]]))

(defn -main []
  (api/with-runtime
    (api/watch :browser)))

Jon11:12:09

turned out I need full examples running shadow-cljs in clj

Jon11:12:16

works fine when I use (server/start!)

thheller11:12:23

ah, hmm for watch you can’t use with-runtime. only for compile.

thheller11:12:37

yeah, start! should work

Jon11:12:54

oh... right, I forgot to change the function

Jon11:12:20

working now with api/with-runtime (api/compile ...)

thheller11:12:50

I really would not recommend running shadow-cljs via clj. it is just strictly worse than using shadow-cljs directly

thheller11:12:05

just because you can doesn’t mean that you should 😉

thheller11:12:08

don’t forget calling (server/stop!)

Jon11:12:38

well... I'm trying to solve the problem of compiling with shadow-cljs twice

thheller11:12:01

clj won’t solve that for you

Jon11:12:25

I will put the scripts in a .clj file, not touching it from REPL actually

thheller11:12:09

clj will always launch a new JVM so I’m not sure what you are hoping to gain

Jon11:12:49

during my assets building, I need to start shadow-cljs twice from npm script

thheller11:12:58

no you do not

thheller11:12:07

create ONE clojure function

thheller11:12:24

(ns build.compile) (defn do-something [] ...)

Jon11:12:26

then I need to run clj to run that.

thheller11:12:34

shadow-cljs clj-run build.compile/do-something

thheller11:12:47

in that function do whatever you want

Jon11:12:55

my build tool was npm scripts.. it does not run Clojure

thheller11:12:58

eg. call (api/watch ...)

Jon11:12:04

anyway I have to write Clojure code..

thheller11:12:47

yeah you’ll need to write clojure … but why use clj?

Jon11:12:20

are you suggesting that I run clj code with shadow-cljs instead of clj

thheller11:12:28

yes, why not?

Jon11:12:53

didn't try clj-run sub-command before

thheller11:12:13

it does literally the same stuff clj does

thheller11:12:29

well it actually does more ..

Jon11:12:41

they look same too me. guess I don't need to duplicate deps in deps.edn if I call shadow-cljs clj-run

Jon11:12:35

how about the warning? Cannot infer target type in expression (. G__35616 -fqn)

Jon11:12:57

not seen it before, only got it when I call APIs

thheller11:12:26

dunno, does it happen with clj-run?

Jon11:12:39

haven't tried yet

thheller11:12:16

clj has a few issues with dependencies, it sometimes loads old versions

thheller11:12:44

it resolves differently than lein or boot. don’t know why … it is alpha so be careful.

Jon11:12:21

tried with clj-run, no warning now

Jon11:12:26

I will try migrate some of my build scripts to Clojure.. hope it runs well

thheller13:12:56

just pushed [email protected] which should start a bit faster. if you already have ssl configured it now supports http2 as well.

tomc16:12:02

@thheller You mentioned in the cljs channel that shadow-cljs has support for using dependencies from npm. Is there a minimal example somewhere of how to require those dependencies in clojurescript code? Should it work the way clojurescript's :npm-deps is supposed to?

thheller16:12:59

:npm-deps is supported when libs use it. in your project you directly npm install (or yarn) yourself

mhuebert01:12:18

:npm-deps should also work for your own project, no? that’s what i have been doing.. then my libs/apps are consistent

thheller16:12:58

minimal example you can clone https://github.com/shadow-cljs/quickstart-browser and use that as a quickstart

Jon16:12:22

shadow-cljs - config: /Users/chen/repo/mvc-works/coworkflow/shadow-cljs.edn version: 2.0.122
shadow-cljs - starting ...
Exception in thread "main" java.lang.AssertionError: Assert failed: (map? http)
	at shadow.cljs.devtools.server.worker$start.invokeStatic(worker.clj:106)
	at shadow.cljs.devtools.server.worker$start.invoke(worker.clj:106)
	at shadow.cljs.devtools.server.supervisor$start_worker.invokeStatic(supervisor.clj:30)
	at shadow.cljs.devtools.server.supervisor$start_worker.invoke(supervisor.clj:23)
	at shadow.cljs.devtools.api$get_or_start_worker.invokeStatic(api.clj:95)
	at shadow.cljs.devtools.api$get_or_start_worker.invoke(api.clj:86)
	at shadow.cljs.devtools.api$watch.invokeStatic(api.clj:112)
	at shadow.cljs.devtools.api$watch.invoke(api.clj:98)
	at shadow.cljs.devtools.api$watch.invokeStatic(api.clj:102)
	at shadow.cljs.devtools.api$watch.invoke(api.clj:98)
	at build.watch$_main.invokeStatic(watch.clj:9)
	at build.watch$_main.invoke(watch.clj:7)

Jon16:12:31

what does this error mean?

thheller16:12:42

what are you doing?

Jon16:12:43

(ns build.watch
  (:require [shadow.cljs.devtools.api :as api]
            [shadow.cljs.devtools.server :as server]
            [clojure.java.shell :refer [sh]]))

(defn -main []
  (server/start!)
  (api/watch :browser))

thheller16:12:48

if you use clj-run you don’t need server/start!

Jon16:12:46

how about api/watch

Jon16:12:19

I think it caused the error. the error remains without server/start!

thheller16:12:47

I need more information, I can’t tell what you are doing

thheller16:12:00

which command do you run?

Jon16:12:12

trying to launch a watch server from API

thheller16:12:23

which command do you run?

Jon16:12:40

yarn shadow-cljs clj-run build.watch/-main

thheller16:12:49

is a server running?

Jon16:12:03

no server

Jon16:12:35

turned out not a good idea to start watch server from a script.

thheller16:12:55

you can do that no problem

Jon16:12:30

what's the right code to start a watch server in Clojure code?

thheller16:12:47

(api/watch :browser)

thheller16:12:01

hang on. I think I found the issue.

thheller16:12:38

so the issue is that clj-run only does a with-runtime which is a lightweight runtime that doesn’t start the embedded server

thheller16:12:46

but watch needs the embedded server

thheller16:12:13

I did not expect anything to run watch via clj-run

mhuebert01:12:13

I think a case came up this week where I thought “hey, we might need to move our watch command into a clj-run process)” but i can’t remember the exact context right now.

mhuebert13:12:54

ah, remembered one. I’m adding a function to my release script which rewrites asset paths in index.html to match the MD5 output names in manifest.edn. I’d like to make sure these paths get re-written to their base forms during dev. I’m trying to think of the most logical way to do this… what came to mind is using clj-run to run my-app.build/watch, and in that function, call the write-static-resource-paths! function once, after the initial compile of api/watch.

Jon16:12:21

a worker?

thheller16:12:30

I think I’ll change it so it just launches the full runtime instead

thheller16:12:28

the issue with watch is that it starts a background thread

thheller16:12:37

that background thread does not keep the process itself running

thheller16:12:50

so it starts, compiles once and then just exits

thheller16:12:53

not what you want

thheller16:12:33

what are you trying to do exactly that shadow-cljs watch the-build doesn’t do?

Jon16:12:46

just exploring, never tried it before

Jon16:12:11

if that feels better, maybe I would rely on npm scripts less

thheller16:12:39

I can make it work easily but it does require you managing threads which is not very fun

thheller16:12:01

"del": "rm -rf dist/*",
    "release": "shadow-cljs release browser",
    "compile-ssr": "shadow-cljs compile ssr",
    "html": "node target/ssr.js && cp entry/manifest.json dist/",
    "build": "yarn del && yarn release && yarn compile-ssr && yarn html"

thheller16:12:10

these or which npm scripts are we talking about?

Jon16:12:21

never mind, actually I would use shadow-cljs command line, if launching it from Clojure is not better.

thheller16:12:44

I’m trying to help you here but I first need to understand what you are doing

thheller16:12:10

there are several things I can do … just need to figure out which makes the most sense

Jon16:12:12

these lines does not include watching part, they are for releasing.

Jon16:12:19

(ns build.release
  (:require [shadow.cljs.devtools.api :as api]
            [shadow.cljs.devtools.server :as server]
            [clojure.java.shell :refer [sh]]))

(defn -main []
  (println (sh "rm" "-rf" "dist/*"))
  (api/with-runtime (api/release :browser))
  (api/with-runtime (api/compile :ssr))
  (println (sh "node" "target/ssr.js"))
  (println (sh "cp" "entry/manifest.json" "dist/")))

Jon16:12:42

I added this script, and it does run faster than my previous version

thheller16:12:47

please stop doing a new ns for everything

thheller16:12:10

(ns app.build) (defn release [] ...) (defn watch [] ...)

Jon16:12:30

will merge them into one file later...

thheller16:12:30

you can invoke functions directly with clj-run, makes things much easier to organize imho

thheller16:12:48

ok so the build.release works with clj-run right?

Jon17:12:03

it's a feature from shadow-cljs, I didn't see clj calls a specific function from CLI

thheller17:12:18

clj can’t call functions directly, only -main yeah

Jon17:12:32

yes, it works, runs faster.

thheller17:12:52

if you use clj-run you also don’t need api/with-runtime

thheller17:12:20

(defn release []
  (println (sh "rm" "-rf" "dist/*"))
  (api/release :browser)
  (api/compile :ssr)
  (println (sh "node" "target/ssr.js"))
  (println (sh "cp" "entry/manifest.json" "dist/")))

thheller17:12:40

so api/watch starts a background thread. its basically an async function. it returns as soon as the first compile completes

thheller17:12:59

(defn watch []
  (api/watch :browser)
  (api/repl :browser))

thheller17:12:35

this would work since the api/repl would “block” until you exit the repl

thheller17:12:42

but thats annoying since you can’t switch anything

Jon17:12:11

no, there's an error

Jon17:12:15

Exception in thread "main" java.lang.AssertionError: Assert failed: (map? http)
	at shadow.cljs.devtools.server.worker$start.invokeStatic(worker.clj:106)
	at shadow.cljs.devtools.server.worker$start.invoke(worker.clj:106)
	at shadow.cljs.devtools.server.supervisor$start_worker.invokeStatic(supervisor.clj:30)

thheller17:12:28

yeah you can’t do that NOW. I can make it work though

thheller17:12:59

the question I want to answer is how to manage the threads most effectively

Jon17:12:18

I think I need to sleep now, too late in here

Jon17:12:35

thanks again

thheller17:12:43

what do you want watch to do that shadow-cljs watch does not do?

thheller17:12:00

if you are literally just calling api/watch that doesn’t make much sense

Jon17:12:32

I was just trying to see if the watch server would launch

thheller17:12:43

I’ll change the embedded server logic so the Assert failed: (map? http) goes away

Jon17:12:08

or, maybe trying to find out if clj CLI can replace npm scripts

thheller17:12:15

still want to figure you what you are trying to do exactly to see if I can make things easier

thheller17:12:04

npm scripts is kinda annoying since it starts a new process for each command

thheller17:12:16

which CLJ just isn’t built for

Jon17:12:40

well, if it is, I have to accept

thheller17:12:08

don’t give up so easily … this is not rocket science

thheller17:12:24

I just need to understand what you are trying to do

thheller17:12:34

I’m still just guessing here

Jon17:12:40

my daily work is in typescript and react, not much time to spend on here recently

Jon17:12:12

I'm just trying to get familiar with them and figure out if things can be easier

Jon17:12:21

found no direction yet

Jon17:12:38

too late,, really going to sleep

thheller17:12:46

sleep well, good night.

mhuebert19:12:33

is there an equivalent to lein deps :tree with shadow

mhuebert19:12:42

i can’t remember..

mhuebert19:12:44

shadow-cljs pom ; mvn dependency:tree

mhuebert19:12:58

does the JVM stuff

thheller20:12:25

not yet. I want to add it eventually. didn’t even know about the mvn stuff but that seems to work

mhuebert20:12:51

yeah, that could be added to shadow’s docs. someone else just told me about it.

mhuebert20:12:20

is there a place where people like myself can add to docs?

mhuebert14:12:55

I added a note about a lein deps :tree to a new “FAQ” page, as I wasn’t sure where else to put it: https://github.com/thheller/shadow-cljs/wiki/FAQ

mhuebert15:12:59

I also added the ‘Production Builds’ and FAQ pages to the sidebar, and re-organized it a bit.

mhuebert15:12:33

I’d like to do something to the ‘Home’ page, because it gives the impression of the wiki being empty (unless you know to look at the sidebar)

thheller22:12:52

FAQ is a good idea, thx

thheller22:12:16

I want to work on the docs in the next few days as well but all suggestions are welcome

thheller22:12:31

feel free to do whatever to the wiki, I really have no idea how to structure it myself

mhuebert14:12:55
replied to a thread:the wiki

I added a note about a lein deps :tree to a new “FAQ” page, as I wasn’t sure where else to put it: https://github.com/thheller/shadow-cljs/wiki/FAQ