Fork me on GitHub
#shadow-cljs
<
2018-03-23
>
Josh Horwitz02:03:16

Is there a good full walkthrough/tutorial of making an app with shadow-cljs?

justinlee02:03:52

@joshua.d.horwitz there is the user guide of course and there is also this starter repo https://github.com/lauritzsh/reagent-shadow-cljs-starter

Josh Horwitz02:03:46

I know Clojure decently and just trying to find where to get intro ClojureScript and start using it

justinlee02:03:49

that’ll help with the tooling. for actually learning the language, the only hard part is getting your head wrapped around a single threaded language. then you need to pick a tech stack (fun!)

grounded_sage04:03:02

I'm following the quickstart browser and I'm getting this when I do the release

grounded_sage04:03:04

------ WARNING #1 --------------------------------------------------------------
 File: cljs/core.cljs:37412:13

 variable Java is undeclared
--------------------------------------------------------------------------------

tony.kay04:03:25

So, @thheller. I’m seeing code generation differences that break fulcro spec’s use of with-redefs. Instead of generated code calling functions like this:

fulcro.ui.forms.form_reduce.call(null,root_form,...)
shadow is generating:
fulcro.ui.forms.form_reduce.cljs$core$IFn$_invoke$arity$3(root_form,...
Then the use of with-redefs redefines fulcro.ui.forms.form_reduce to a function, and we end up with errors like this: fulcro.ui.forms.form_reduce.cljs$core$IFn$_invoke$arity$3 is not a function I can see that this looks like an optimization, but it definitely breaks code that has been working against clj and cljs for years. Seems to me it generally breaks cljs with-redefs

levitanong06:03:56

@thheller tried making a minimal case with the thing we were puzzling over with @tony.kay. Not sure if I found the same thing because this time i’m getting an actual error. Posted an issue: https://github.com/thheller/shadow-cljs/issues/225

thheller07:03:41

@tony.kay that is probably broken because shadow-cljs defaults to :static-fns true. can you trying compiling with :compiler-options {:static-fns false}?

tony.kay13:03:29

Ah I see. I have seen that compiler option before. I guess I didn't expect it to break core functions.

thheller13:03:10

@tony.kay I have this issue thats bugging me about om/fulcro query setup. the point of query language like graphql to me is that components just ask for what they want and don't have to worry where the underlying data is coming from (or its shape)

thheller13:03:32

yet in om/fulcro the components ALSO basically define the database schema via idents

thheller13:03:41

or am I just understanding idents wrong?

thheller13:03:18

idents just break the entire model for me

thheller13:03:53

yes having a normalized database is nice

thheller13:03:08

but the components shouldn't be the ones deciding how the normalization happens in my mind

thheller13:03:46

I guess I might just need to use fulcro more and let it sink in but every time this nagging feeling just keeps coming up

thheller13:03:41

I understand why idents are on the components but it still feels like a mistake

tony.kay13:03:13

Glad to talk about it, not sure this channel is the right place

thheller13:03:04

thought we were in #fulcro 😛

lwhorton19:03:25

hey guys is there an existing idiom for module-hash-names and your index.html file management?

lwhorton19:03:58

initially I was thinking of writing something that fetches the manifest.json, then dynamically adds a script tag to fetch my actual code source by parsing the name out of the manifest

lwhorton19:03:15

but that adds quite a bit of overhead right at the app load time, so preferably a compile-time solution already exists

thheller19:03:27

do you have a static html file?

thheller19:03:43

if its generated by the server the manifest files should help

lwhorton19:03:31

i do have a static file, so ill take a look at clj-run

thheller19:03:43

(ns your.build
  (:require
    [shadow.cljs.devtools.api :as shadow]
    [clojure.edn :as edn]
    [clojure.string :as str]))

(defn release []
  (shadow/release :your-build)
  (let [manifest
        (-> (slurp "public/js/manifest.edn")
            (edn/read-string))

        index-src
        (slurp "public/index.html.src")

        index
        (reduce
          (fn [index-src {:keys [module-id output-name]}]
            (let [marker (str (name module-id) ".js")]
              (str/replace index-src marker output-name)))
          index-src
          manifest)]
    
    (spit "public/index.html" index)))

lwhorton23:03:43

I’m having difficulty with the related (shadow/watch) api. is there something different about the expectations of this fn?

lwhorton23:03:15

some complaints about “Exception in thread “main” java.lang.AssertionError: Assert failed: (map? http) at shadow.cljs.devtools.server.worker$start.invokeStatic(worker.clj:103)” when I try to do (shadow/watch (keyword build-id) where build-id is provided as a string from the cli

thheller19:03:53

shadow-cljs clj-run your.build/release

thheller19:03:14

looks at a public/index.html.src replaces <srcipt src="/js/main.js"> with <srcipt src="/js/main.<the-hash>.js">

thheller19:03:37

pretty hacky but should work. could make it more reliable by using better placeholder or something like that

thheller19:03:33

could even generate the full html from hiccup or so

lwhorton19:03:00

i had something like the above-- or rather, was writing something like that right now. i guess my next question is: is there a way to use a pre-hook so I can shadow-cljs … oh wait

lwhorton19:03:07

hah, that’s the purpose of shadow/release eh?

thheller19:03:31

indeed. thats the same as calling shadow-cljs release your-build just from the clojure api

lwhorton19:03:44

okay, that’s neat — although slightly peculiar to change the “standard” api

lwhorton19:03:04

i would have thought I could use a :pre-hook and maintain shadow-cljs release prod, and in that release hook templating would take place

thheller19:03:10

I'm still debating the proper way to add hooks into the build process

thheller19:03:26

because you can break things easily that way

lwhorton19:03:28

it’s a lot to think about — once per build, or once per each reload, etc.

thheller19:03:32

but yes there should be a way to hook in

thheller19:03:08

easiest way to do it currently is just via the clojure api and clj-run

thheller19:03:22

that leaves the build process alone and just lets you run before/after easily

thheller19:03:05

custom builds also let you do this but thats much too low level for most cases

lwhorton19:03:46

yea thanks for this; ill use the clj-run which will also allow me pass command line args, tightening up the above “hacky” solution a bit

👍 4
mhuebert20:03:47

does this error make any sense to you? I am masochistically trying to get my shadow builds working everywhere, this time during slug compilation on heroku.

remote:        > shadow-cljs start && shadow-cljs clj-run build.build/release && webpack -p;
remote:
remote: shadow-cljs - config: /tmp/build_248d245eeae37c14789671b54890ae63/_spark-spa/shadow-cljs.edn version: 2.2.14
remote: shadow-cljs - server starting .events.js:160
remote:       throw er; // Unhandled 'error' event
remote:       ^
remote:
remote: Error: spawn clojure ENOENT
remote:     at exports._errnoException (util.js:1026:11)
remote:     at Process.ChildProcess._handle.onexit (internal/child_process.js:182:32)
remote:     at onErrorNT (internal/child_process.js:348:16)
remote:     at _combinedTickCallback (internal/process/next_tick.js:74:11)
remote:     at process._tickCallback (internal/process/next_tick.js:98:9)
remote:     at Module.runMain (module.js:592:11)
remote:     at run (bootstrap_node.js:394:7)
remote:     at startup (bootstrap_node.js:149:9)
remote:     at bootstrap_node.js:509:3
remote: npm ERR! code ELIFECYCLE
remote: npm ERR! errno 1
(I switched to shadow-cljs start && shadow-cljs release... because shadow-cljs release... doesn’t fail, it just prints “starting with clojure” and then heroku silently moves on to the next process and nothing is compiled)

thheller20:03:47

looks like clojure maybe isn't on the path?

mhuebert22:03:33

ah yikes, that’s probably it. the clojure buildpack wouldn’t have that yet

mhuebert23:03:13

so, the following works to install clojure on heroku, assuming you are in the heroku/node buildpack after the heroku/jvm buildpack: curl -O && chmod +x linux-install-1.9.0.358.sh && ./linux-install-1.9.0.358.sh -p $(pwd)/.heroku/node

justinlee21:03:56

@thheller what do you think about a feature on the browser side that gives some like warning that you’ve disconnected from the shadow-cljs server and/or a feature that lets you know if the build is broken. sometimes you think you’re looking at live code but you’re not

thheller22:03:49

sure sounds like a good idea. open to suggestions to how that should look

justinlee22:03:49

maybe the simplest thing is to deal with disconnection: seems to me that a popup similar to the one that signals a recompilation which simply shoes the cljs logo and says “disconnected” would be enough. query: does shadow-cljs try to reload once disconnected? maybe it should keep retrying, which would eliminate the problem most of the time