Fork me on GitHub
#shadow-cljs
<
2020-05-26
>
Tuomas05:05:31

Hey, I’m a relatively new clojurian. I got my own stuff working by adding

:compiler-options {:optimizations :simple}
but I also want to investigate further to learn more and mby help others. I have a fulcro app with shadow-cljs and I used Formidable’s Victory for a simple bar chart. I colored the bar fills with a function
(fn [data]
                                     (let [integer-value (.. data -datum -rpn)]
                                       (cond
                                         (> integer-value first-threshold)) "#c43a31"
                                         (> integer-value second-threshold) "#ffa500"
                                         :else "#00ff00")))
While I was developing the colouring worked, but after deploying a noticed it was all "#00ff00" . The bug seemed to appear randomly on my local environment, but eventually I noticed that it happens always after
shadow-cljs release main
And after changing code (and automatically compiling with simple) it started working. With simple optimizations I got it working after deploying too. Am I breaking some obvious rule, or is this something I should investigate more and try to fix?

thheller06:05:11

@koivistoinen.tuomas turn on :infer-externs :auto https://shadow-cljs.github.io/docs/UsersGuide.html#externs that will likely give you a warning about the (data -datum -rpn). so you ^js data whereever that is coming from and that should fix it.

👌 4
wilkerlucio07:05:07

does :exclusions works on shadow? I'm trying to use a custom version of test.check that I built (on my group name), but because there is some dep trying to load the original test.check they are conflicting, I tried put :exclusions [org.clojure/test.check] in every dep a I have, but that didn't worked (I'm using :dependencies from shadow itself in this project), is there a way around it?

thheller07:05:22

should work? [some-dep "version" :exclusions [foo/bar]?

thheller08:05:00

oh wait. shadow-cljs itself has a dependency on test.check because of pathom

thheller08:05:11

so thats probably where it is coming from

thheller08:05:53

can't remember the details. maybe thats not current anymore?

wilkerlucio08:05:40

humm, pathom should not need that unless you are doing generative stuff with it

wilkerlucio08:05:35

my case is a bit specific due to I need to use a custom version of test.check that I forked, and this project so far needs to use shadow, I could get shadow to use my version by releasing with a bigger version number, but now getting a lot of warnings due to duplication of namespaces on classpath

thheller08:05:05

those should be gone with newer versions? it doesn't scan the classpath for cljs sources anymore?

thheller08:05:15

@wilkerlucio just tested, pathom won't start without test.check on the classpath.

wilkerlucio08:05:33

ok, I can check that, this shouldn't be required

thheller08:05:05

fails because of that

wilkerlucio08:05:18

ok, updating it in a bit

wilkerlucio08:05:20

thanks for the precise pointing 🙂

wilkerlucio09:05:06

@thheller eql 1.0.0 now has generative features on a different ns, pathom 2.3.0-alpha9 bumps EQL, that should fix it

👍 4
thheller09:05:08

just a thought but you could maybe move all the spec stuff into a separate ns. then people can add eqn-query-language.specs to :preloads if wanted. you can get rid of the goog-define that way. right now I doubt that most people are aware of the INCLUDE_SPECS define?

thheller09:05:47

its just dev-only stuff anyways

wilkerlucio09:05:32

makes sense, I think I'll move on this direction next

thheller09:05:37

I also thought about making that a bit automatic in shadow-cljs. so you can set :include-specs true or so and it auto includes foo.bar-specs in development if foo.bar is part of the build

thheller09:05:54

since dev-only specs are hard to keep out of the main build otherwise currently

wilkerlucio09:05:38

the main problem there I think is that its hard to know if a spec is intended for prod or not, because some are

wilkerlucio09:05:20

in recent projects I've been using guardrails, with that I use the guardrails fn to define dev stuff, and spec directly for prod stuff, this way at least its a clean separation

thheller09:05:42

well prod specs you'd just include normally

wilkerlucio09:05:01

ah, sorry, I think I understand now

wilkerlucio09:05:15

about a pattern to auto-require *-specs during dev

thheller09:05:00

yeah. like now pathom includes edn-query-language.core. with the flag shadow-cljs would detect edn-query-language.core-specs and also include that automatically in dev

thheller09:05:16

good thing about that way is that the specs can directly include the core ns and use it as a alias and easily do fdef for it

thheller09:05:39

if core would require core-specs that not easily possible because of the circular reference

thheller09:05:00

but yeah guardrails is much more involved so that wouldn't work

thheller09:05:42

last time I checked just including guardrails did leave some stuff after :advanced even if never used

wilkerlucio09:05:32

was that a long time ago? I know tony made some changes to just inject validation code instead of rely on instrumentation, I wonder if that makes the difference on it

thheller09:05:01

so you can actually ensure that nothing is left

thheller09:05:11

its been a while yes

wilkerlucio09:05:25

but maybe that wouldn't work for guardrails, given I still need guardrails in prod to generate the standard fns

thheller09:05:52

yeah, your alias ns would do exactly that

wilkerlucio09:05:06

ah, ok, not a transparent stub thing, cool

thheller09:05:18

the tracing stuff does that too. without the alias it adds the tracing code. with the alias it just does a regular defn

wilkerlucio09:05:40

what tracing stuff?

thheller09:05:24

re-frame example from above

thheller09:05:24

the issue why we need this is that even if you have a macro that does nothing

thheller09:05:36

you cannot get rid of the ns requires the namespace providing the macros has

thheller09:05:54

and those may do stuff that don't play well with :advanced

djanus13:05:13

hey, is there a way to tell shadow-cljs to not generate a huge index.js for debug builds, instead going for document.write('<script...>') like vanilla cljs tooling?

djanus13:05:21

case in point: I have a react-native app and RN insists on reloading the whole thing every time I change something, even though RN's fast refresh is turned on

thheller15:05:22

@dj942 for :browser there is an option to emit multiple files. for react-native there is not.

thheller15:05:59

last time I checked there were 2 options for turning of reload in RN. with both off it would only check the generated shadow-cljs output when loading the app but never while its running

djanus15:05:32

I don't event mind longish reloads all that much, but I'd prefer not to lose app state every time a reload happens

thheller15:05:53

sounds to me like you are letting react-native reload stuff

thheller15:05:00

shadow-cljs reload would keep your state

djanus15:05:19

yeah, that's correct

djanus15:05:52

I guess I need to read up metro bundler's documentation on how to disable reload

thheller15:05:18

I never configured anything in metro

thheller15:05:29

just the debug menu thing in the app itself

thheller15:05:53

fast refresh and live-reload or whatever the other one is called

thheller15:05:56

there are two options

djanus15:05:41

looks like there's only one in react-native 0.62, "disable fast refresh"

thheller15:05:00

no clue, last time I checked there were 2 options

thheller15:05:08

can't remember which version that was though

djanus15:05:09

it works! although it doesn't trigger a rerender after reload

djanus15:05:55

I guess there's a callback somewhere

thheller15:05:59

that part is up to you, the demo repo I created has an example of how you can set that up

djanus15:05:28

huge thanks

Derek Passen15:05:50

2.9.9 looks to have introduced a regression with regard to deps.cljs and a package.json file

IllegalArgumentException: No matching field found: exist for class .File
        clojure.lang.Reflector.getInstanceField (Reflector.java:397)
        clojure.lang.Reflector.invokeNoArgInstanceMember (Reflector.java:440)
        shadow.cljs.devtools.server.npm-deps/install-deps (npm_deps.clj:160)
        shadow.cljs.devtools.server.npm-deps/install-deps (npm_deps.clj:131)
        shadow.cljs.devtools.server.npm-deps/main (npm_deps.clj:242)
        shadow.cljs.devtools.server.npm-deps/main (npm_deps.clj:228)
        shadow.cljs.devtools.cli-actual/main (cli_actual.clj:141)
        shadow.cljs.devtools.cli-actual/main (cli_actual.clj:132)
        clojure.core/apply (core.clj:669)
        clojure.core/apply (core.clj:660)
        shadow.cljs.devtools.cli-actual/-main (cli_actual.clj:219)
        shadow.cljs.devtools.cli-actual/-main (cli_actual.clj:217)
        clojure.lang.Var.applyTo (Var.java:705)
        clojure.core/apply (core.clj:665)
        clojure.core/apply (core.clj:660)
        shadow.cljs.devtools.cli/-main (cli.clj:75)
        shadow.cljs.devtools.cli/-main (cli.clj:67)
        clojure.lang.Var.applyTo (Var.java:705)
        clojure.core/apply (core.clj:665)
        clojure.main/main-opt (main.clj:514)
        clojure.main/main-opt (main.clj:510)
        clojure.main/main (main.clj:664)
        clojure.main/main (main.clj:616)
        clojure.lang.Var.applyTo (Var.java:705)
        clojure.main.main (main.java:40)

Derek Passen15:05:58

Dropping back to 2.9.8 and it works

Derek Passen15:05:32

exist vs exists?

thheller16:05:12

yeah, fixed in 2.9.10

Pavel Klavík19:05:10

Hi, I am trying to build a small HTTP server in NodeJS. I am trying to use macchiato, but after requiring the dependency [macchiato.server :as http], I get the following error on startup:

SHADOW import error C:\Shared\orgpad\.shadow-cljs\builds\preview\dev\out\cljs-runtime\shadow.js.shim.module$xregexp.js
Error: Cannot find module 'xregexp'
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:582:15)
    at Function.Module._load (internal/modules/cjs/loader.js:508:25)
    at Module.require (internal/modules/cjs/loader.js:637:17)
    at require (internal/modules/cjs/helpers.js:22:18)
    at C:\Shared\orgpad\.shadow-cljs\builds\preview\dev\out\cljs-runtime\shadow.js.shim.module$xregexp.js:3:33
    at global.SHADOW_IMPORT (C:\Shared\orgpad\preview\preview.js:64:44)
    at C:\Shared\orgpad\preview\preview.js:2329:1
    at Object.<anonymous> (C:\Shared\orgpad\preview\preview.js:2342:3)
    at Module._compile (internal/modules/cjs/loader.js:701:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:712:10)

thheller19:05:07

thats the node message for a missing npm install xregexp?

Pavel Klavík20:05:34

cool, it works, thx

Pavel Klavík20:05:49

what is the approach for hot code reloading? stopping the server and starting it again?

lilactown21:05:09

if you var-quote your routes, it will dynamically look up the function each invocation

lilactown21:05:34

from their docs:

(def routes
  ["/" {""        {:get #'home}
        "message" {:post #'message}}])

thheller21:05:16

meh vars in CLJS, maybe #(home %) might be better? assuming it just gets one arg 😉

Pavel Klavík22:05:09

It seems to work sufficiently well for the small size of the server 🙂

thheller20:05:54

no clue. I've never used macchiato

cjsauer22:05:37

Is is possible to run shadow-cljs watch on a build without injecting nREPL related things into the output? I’m using the :node-script target and have a coworker who doesn’t use a REPL (I know, I’ve tried to convince him), but would still like to have the auto-compile functionality of the watch whenever the file is changed.

dpsutton22:05:57

> The nREPL server can be disabled by setting :nrepl false

dpsutton22:05:15

wait, what do you mean injecting nrepl?

thheller22:05:48

@cjsauer there are no nrepl related things injected into the JS output, it just connects the websocket which handles hot-reload and also the REPL

thheller22:05:43

so its all the same websocket anyways, nothing to turn off

cjsauer22:05:56

Ah ok. That is what prevents the development node script from exiting yea? In a normal workflow, I’d run node my_script.js and then connect my REPL. In his case tho, he’d like to run the script manually upon every change, and have it exit normally.

thheller22:05:28

you can set :devtools {:enabled false} in the build. then it won't connect and just exit

cjsauer22:05:41

Cool, that’s what I’m after :thumbsup:

thheller22:05:26

general question I guess: I'm thinking about allowing a shadow-cljs.local.edn or so which could override shadow-cljs.edn config stuff

thheller22:05:06

seems like quite often people have different preferences when working in teams, so that way each user could have their own local config

thheller22:05:36

I really dislike using env vars to stuff like that

cjsauer22:05:20

I’m having exactly this conversation with my coworker at the moment (he just asked me how to read env vars in shadow-cljs.edn). A local config file would be great for things like this.

thheller22:05:23

like you could keep devtools while your coworker can disable it 😛

thheller22:05:51

shadow-cljs watch the-script --config-merge "{:devtools {:enabled false}}" also works though

cjsauer22:05:17

Ooh that’s nice, didn’t know that. I was considering having two builds: :script-calvin and :script-eric haha

thheller22:05:51

hehe that also works 😛

cjsauer22:05:12

I appreciate your help and hard work @thheller. Thanks for the guidance.

❤️ 16