Fork me on GitHub
#shadow-cljs
<
2018-07-10
>
grounded_sage01:07:27

Hey I've nearly finished putting together the first iteration of a build tool based on shadow. I'm striving for 100/100 lighthouse audit out of the box when testing the release locally on the shadow-cljs server. The failing points I have are. 1. Does not redirect HTTP traffic to HTTPS 2. Does not use HTTP/2 for all of its resources Is there a simple way to set this up?

grounded_sage06:07:08

There is some strange behaviour when I use srcset on an img tag. For some reason using this attribute triggers a network request for the same image every time I change the browser size. When hosted on Netlify this does not happen.

thheller06:07:36

@oscar shadow-cljs is focused on CLJS development. if you want to build a CLJ server you should do so using CLJ tools which you are going to need anyways for release (by which I mean build your own CLJ webserver, do not piggyback on the built-in server)

thheller06:07:05

@grounded_sage no not currently. feels a bit out of scope. since HTTPS requires domain names the only way to do this is running on localhost:80 + localhost:443. if you run on http://localhost:8080 you cannot redirect to https://localhost:8080 but must use a different port which then is treated as a different server and the whole spiel begins again

thheller06:07:31

@lilactown @wilkerlucio ^:export doesn't actually preserve the "namespace". there are no namespaces in :advanced compilation. it just basically sets your.app.foo = xW; after the fact. so what once was your.app.foo became xW and is then reassigned later.

gleisonsilva12:07:53

Hello guys! I'm just starting with shadow-cljs on a new project... has anyone a example of using material-ui with it? I've tried the cljsjs way, but I saw that this is not supported anymore... I'm a bit confused...

thheller12:07:49

@gleisonsilva the whole point is to use npm directly, so you npm install it and start using it

thheller12:07:23

I can "translate" if you have an example of the "cljsjs way"

thheller12:07:39

how would you use that though?

thheller12:07:05

like an example react example

gleisonsilva12:07:24

i'm not sure... i'm a begginer with both (shadow-cljs and material-ui react components) i'm trying to find examples of react components with shadow-cljs, but I haven't found yet..

thheller12:07:40

which react wrapper are you using? reagent?

gleisonsilva12:07:54

yes. i'll use reagent

thheller12:07:04

showing the use of react-avatar-editor. you can substitute that with material-ui or any other of the material design wrappers

gleisonsilva12:07:24

tks, @thheller! I'll check that out.

hlolli12:07:00

@gleisonsilva for boilerplate, I did this

(:require
            ["material-ui/styles" :as styles]
            ["material-ui/AppBar" :as AppBar]
            ["material-ui/styles/MuiThemeProvider" :as Theme]
)
(def muiTheme
  (styles/createMuiTheme
   #js {:palette #js {:primary   #js {:main         "#7796a8" ;; "#3f50b5"
                                      :dark         "#848F92" ;; "#BCCACD"
                                      :light        "#e0e7eb" ;;"#002884"
                                      :contrastText "#fff"}
                      :secondary #js {:light        "#7796a8" ;; "#3f50b5"
                                      :main         "#e0e0e0" ;;"#757ce8"
                                      :dark         "#e0e7eb" ;;"#002884"
                                      :contrastText "#000"}
                      :stepper   #js {:iconColor "green"}}}))

..later...
[:> Theme/default {:theme muiTheme} .... rest of app]

oscar13:07:24

@hlolli @gleisonsilva you can avoid having to do Theme/default. If your require is instead ["material-ui/styles/MuiThemeProvider" :default Theme] then you can just say Theme.

oscar13:07:11

@gleisonsilva also, I'd suggest directly using Material-UI v1 (which is a lot different than v0.x). Translation from JS is pretty straightforward and the new require strings ("@material-ui/core/styles" work just fine as :require statements in shadow-cljs. I've been using it for a while so feel free to direct questions my way.

kenny15:07:29

I just updated to the shadow-cljs 2.4.17 and now I am getting DEBUG logs from shadow-cljs in my console. Is there a way to configure shadow-cljs logging?

thheller15:07:27

what do you mean? logging hasn't changed for quite a long time?

kenny15:07:20

For example, I'm getting messages like these:

18-07-10 15:23:32 Kenny-Compute-Software-Macbook.local DEBUG [shadow.cljs.devtools.server.worker.impl:286] - :shadow.cljs.devtools.server.worker.impl/runtime-msg 7b6011fe-e547-4b81-8ee2-fba61e36daf8 :ping

kenny15:07:00

I did not receive those before. I also switched to use deps.edn.

thheller15:07:07

ah thats the reason

thheller15:07:28

the shadow-cljs npm thing sets up logging. deps.edn does not.

kenny15:07:06

What do you mean? I was using the lein integration before.

thheller15:07:08

do you use any logging library?

thheller15:07:42

java logging library I mean. logback, log4j, ...?

kenny15:07:07

Not in my cljs app. It is possible some other dependency is pulling one of those in though.

thheller15:07:35

handlers=java.util.logging.FileHandler, java.util.logging.ConsoleHandler

.level=INFO

java.util.logging.FileHandler.limit=5000000
java.util.logging.FileHandler.count=3
java.util.logging.FileHandler.append=true
java.util.logging.FileHandler.formatter=java.util.logging.SimpleFormatter
java.util.logging.FileHandler.level=INFO

java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter
java.util.logging.ConsoleHandler.level=WARNING

java.util.logging.SimpleFormatter.format=[%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS - %4$s] %5$s%6$s%n


java.util.logging.FileHandler.pattern=.shadow-cljs/shadow-cljs.log

thheller15:07:59

this is the default logging config used when using shadow-cljs to run stuff

thheller15:07:55

need to append -Djava.util.logging.config.file=logging.properties to your jvm args

thheller15:07:16

I think its :jvm-opts ["-Djava.util.logging.config.file=logging.properties"] in deps.edn

thheller15:07:38

I don't know why you are seeing debug messages though. those are usually hidden by default so you might have some logging going on already

thheller15:07:45

I can probably automate that for the deps.edn integration

kenny15:07:06

Yeah, it is strange. I have had numerous cases where tools-deps resolves things differently than lein which causes issues similar to this one.

thheller15:07:48

yeah tools.deps is stricter. which is good but different from lein so sometimes has unexpected results

kenny15:07:38

Agreed. I'll fiddle with exclusions to see if I can get the default behavior back.

thheller15:07:54

any particular reason you fight with lein or tools.deps instead of just using the built-in dependencies support?

kenny15:07:07

Yes, twofold. 1. We switched to tools.deps to use Git dependencies. Does shadow-cljs have support for this? 2. I like to use the lein-cooper plugin to start shadow-cljs and node-sass via a single command (i.e. lein dev).

thheller15:07:29

1) is not supported no. 2) is possible via clj-run

kenny15:07:49

What is clj-run?

kenny15:07:03

Interesting! I'll give that a try.

kenny15:07:30

Adding some exclusions fixed the DEBUG issue.

thheller15:07:54

thx will fix that

kenny16:07:23

Strange error on my first cut. I would've expected the exception immediately:

kenny@Kenny-Compute-Software-Macbook ~/c/ui-frontend> shadow-cljs clj-run dev.build/start-dev
shadow-cljs - config: /Users/kenny/compute_software/ui-frontend/shadow-cljs.edn  cli version: 2.4.17  node: v10.1.0
shadow-cljs - starting via "clojure"
shadow-cljs - HTTP server for :app available at 
shadow-cljs - server version: 2.4.17
shadow-cljs - server running at 
shadow-cljs - socket REPL running on port 52269
shadow-cljs - nREPL server started on port 9999
^Cshutting down ...
failed to run function: dev.build/start-dev
{:tag :shadow.cljs.devtools.cli/clj-run, :main-sym dev.build/start-dev}
ExceptionInfo: failed to run function: dev.build/start-dev
        clojure.core/ex-info (core.clj:4739)
        clojure.core/ex-info (core.clj:4739)
        shadow.cljs.devtools.cli/do-clj-run (cli.clj:124)
        shadow.cljs.devtools.cli/do-clj-run (cli.clj:79)
        shadow.cljs.devtools.cli/blocking-action (cli.clj:140)
        shadow.cljs.devtools.cli/blocking-action (cli.clj:130)
        shadow.cljs.devtools.cli/main (cli.clj:191)
        shadow.cljs.devtools.cli/main (cli.clj:146)
Caused by:
No configuration for build ":my-build" found.
shutdown complete.
The issue was I copy and pasted the code from the example and forgot to update the build id to the build id for my project.

thheller16:07:56

what do you mean immediately? the exception was caused by your code so it can't happen "earlier"?

kenny16:07:20

Oh, I think I know the problem. I have a call to sh that did not complete because it is node-sass's watch command. So I'm guessing the call to shadow/watch did not occur until after I ^C'ed.

(defn start-dev
  {:shadow/requires-server true}
  [& args]
  (prn (shell/sh "npx" "node-sass" "resources/css/" "--watch" "--recursive" "--output" "resources/public/css"))
  (shadow/watch :app))

thheller16:07:32

correct. shell/sh never exits so watch is never called

kenny16:07:22

Hmm. Probably need to find a better shell library then.

thheller16:07:34

hmm now that I think about it there is no easily accessible "run in background but show streaming output" type of utility fn built-in

kenny16:07:50

Right, that's exactly what I need.

thheller16:07:27

you can use ProcessBuilder I guess

kenny16:07:38

Yeah, I suppose so.

thheller16:07:20

(let [cmd ["npx" "node-sass" "resources/css/" "--watch" "--recursive" "--output" "resources/public/css"]]
  (future
    (-> (ProcessBuilder. cmd)
        (.inheritIO)
        (.start)
        (.waitFor))))

kenny16:07:40

Will killing the parent process also kill the child?

thheller16:07:52

hmm how does lein-cooper handle the output? are they all just dumping to stdout?

kenny16:07:13

Yes. + some nice formatting.

kenny16:07:27

And if a subproc fails, the whole thing exits.

kenny16:07:25

I forgot I actually extracted lein-cooper into a self-contained library several months ago haha: https://github.com/ComputeSoftware/join-process/blob/master/src/join_process/core.clj. I think I can use that here.

thheller16:07:59

btw you can also just use tools.deps directly. you do not have to go through shadow-cljs

thheller16:07:23

clojure -m shadow.cljs.devtools.cli compile app is identical to shadow-cljs compile app

thheller16:07:25

can just replace shadow-cljs with clojure -m shadow.cljs.devtools.cli for any command the only thing you miss out of is the server support. see https://code.thheller.com/blog/shadow-cljs/2017/11/18/the-many-ways-to-use-shadow-cljs.html

kenny16:07:18

Not sure I understand the advantage you gain by doing that.

thheller16:07:52

you don't really. the result should be the same.

kenny16:07:36

So I got it to work like this:

(ns dev.build
  (:require
    [join-process.core :as join-proc]))

(defn start-dev
  [& args]
  (join-proc/join-process [{:name "cljs"
                            :cmds ["shadow-cljs" "watch" "app"]}
                           {:name "sass"
                            :cmds ["npx" "node-sass" "resources/css/" "--watch" "--recursive" "--output" "resources/public/css"]}]))

(defn -main
  [& args]
  (apply start-dev args))
Running this command clj -A:dev:start-dev with these deps.edn :aliases:
{:dev  {:extra-paths ["env" "devcards-src"]
        :extra-deps  {compute/join-process {:git/url ""
                                            :sha     "3068d554275575f499c0bd999ea3e17fc41eabad"}}}
 :start-dev {:main-opts ["-m" "dev.build"]}}

kenny16:07:17

I would've expected this to work though:

kenny@Kenny-Compute-Software-Macbook ~/c/ui-frontend> shadow-cljs clj-run dev.build/start-dev
shadow-cljs - config: /Users/kenny/compute_software/ui-frontend/shadow-cljs.edn  cli version: 2.4.17  node: v10.1.0
shadow-cljs - connected to server

^C⏎
However, nothing was printed to the console.

thheller16:07:57

note the shadow-cljs - connected to server. a server instance is already running

kenny16:07:24

How does that change the output?

thheller16:07:48

the older server instance probably still has the older code loaded?

kenny16:07:50

You're right - restarting the server fixed it. Makes sense but was a bit confusing.

thheller16:07:56

its probably still better to use clj directly since clj-run assumes you will be running shadow-cljs code and loads all the namespaces

thheller16:07:09

which will make startup way slower compared to just clj directly

thheller16:07:29

since all you do run 2 new separate processes

kenny16:07:47

Makes sense