Fork me on GitHub
#shadow-cljs
<
2019-11-12
>
Nolan00:11:17

sounds uncannily similar to what happens to type info in ocaml (and probably other HMs), only for JS, which only makes it that much more insane

nickmbailey00:11:00

does clojurescript metadata have to be attached inline? attaching the export metadata with 'with-meta' or 'vary-meta' doesn't seem to work

thheller00:11:25

@nickmbailey yes, needs to be completely static. are you trying to attach the export meta in a macro?

thheller00:11:55

then try

`(def ~(with-meta the-sym {:export true}) ...)

Drew Verlee00:11:05

Whats the best way to inspect props that are passed in a react app at run time. Assuming a typical shadow-cljs setup in development mode? 1. The browsers react "components" view seems munged by the clojurescript, as in you just get "Object". i suppose thats workable because you can open it up. 2. There are contexts where it seems hard to even print the state, possible due to this issue: https://github.com/binaryage/cljs-devtools/issues/25. Though the fix at leasts lets you print the props without an error.

thheller00:11:29

including that bit of code should make it work

thheller00:11:41

maybe? not sure

thheller00:11:31

oh thats also in the gh issue

Drew Verlee00:11:20

yea. šŸ™‚ .That lets me print the props, which might be as good as it gets and all i need in this case. I'm just curious if i should be looking elsewhere, as this issue would seem to be very common place.

thheller00:11:41

I just (js/console.log ...) them like normal

thheller00:11:33

I don't use cljs-devtools most of the time though

lilactown00:11:29

what I typically do is navigate to the component in the React DevTools, then click the ā€œbugā€ to log the component and itā€™s state / props to the console

šŸ‘ 4
lilactown00:11:32

thheller, Iā€™m curious what your thoughts are (if any) about ā€œdynamicā€ code splitting

lilactown00:11:20

it seems to be getting quite popular in e.g. webpack / parcel / etc. to determine how to split the bundle based on usage of dynamic import()

lilactown00:11:59

I see the appeal, as setting up an entrypoint can be onerous if you want to just lazy load a component or whatever

thheller00:11:02

yeah dunno. I don't like it that much but it requires less config

šŸ˜‚ 4
šŸ‘ 4
thheller00:11:25

I don't like import() creeping into libraries though. that seems like a horrible idea

thheller00:11:04

configuring :modules can be quite tedious so I definitely see the appeal

lilactown00:11:13

yes definitely. especially since it relies on bundler behavior. maybe once dynamic import is in most browsersā€¦ but even then, dynamically importing a lib could cause a cascade of :poop: šŸ˜µ

thheller00:11:44

yeah I don't like libraries deciding that my code should be split

lilactown00:11:17

yeah. Iā€™m wondering if there could be a way to macro-away some of the pain of :modules. I assume it would rely on something shadow-cljs specificā€¦

thheller00:11:03

I experimented with a bunch of things a while ago but really the coming up with a good "graph" is the problem

thheller00:11:19

I certainly don't know enough graph stuff to figure that out šŸ˜›

thheller00:11:24

I kinda like that I can configure my modules how I like and fine tune when needed

thheller00:11:47

with "automatic" webpack style config everything is kinda random and all sorts of weird sized chunks

Nolan00:11:53

what would be neat is a cli tool that would do all the neato graph analysis and make a recommendation

thheller00:11:24

indeed. build that now please šŸ™‚

šŸ˜‚ 4
Nolan00:11:55

yeah, id love that. if only i knew literally anything about graphs

lilactown00:11:50

I wish there was a way to at least separate the code you write to import from the module config

lilactown00:11:03

Or is that what shadow.loader does now?

thheller00:11:53

that is the latest bit of "sugar", so you don't have any references of "modules" in your code. don't need to remember what something is in

lilactown00:11:08

Right yes. I remember I wrote a bunch of module loader sugar for my last employer before that existed

lilactown00:11:20

I didn't quite get to the point of resolving which module an ns existed in though

levitanong11:11:19

shadow-cljs build hooks can specify what compilation stage they are relevant in, via shadow.build/stage. Is there additional support for other things like shadow.build/mode to control whether or not the hook activates in dev mode or release mode?

thheller11:11:46

just check it in the build hook and do nothing if it doesn't match your intended mode

levitanong11:11:01

Yeah that was my fallback. Was curious šŸ˜…

levitanong11:11:19

@thheller Iā€™m getting warnings about the absence of refactor-nrepl and cider-nrepl when compiling from a clojure (i.e. starting the shadow-cljs server and compiling stuff). It doesnā€™t seem to stop me from compiling, but I just want to make sure with you whatā€™s happening there. Like, should I actually require those two libs when compiling?

thheller11:11:55

shadow-cljs doesn't use any of that

thheller11:11:12

it is probably your nrepl config

levitanong11:11:22

Alright, cool. Thanks!

orestis13:11:46

Much as I love looking at efforts to do away with React, then I remember how much work is to actually produce a nice drag-and-drop component like react-beautiful-dnd and cry in my coffee.

šŸ’Æ 4
thheller13:11:30

it is nice to tap into the react ecosystem sometimes ... but in my experience that has been more trouble than actual benefit. constantly breaking packages/apis or just overly bloated packages.

orestis14:11:38

Yeah, Iā€™m in this situation. I decided to drop to the React ecosystem only when strictly necessary, even we end up with a bunch of ā€œNIHā€ stuff. The recent hooks work has finally allowed us to make use of smaller dependencies that we could easily rewrite if we ever wanted to. Instead of relying, say, on the steaming pile of react-bootstrap.

levitanong13:11:34

@thheller sorry to be bothering you so much. When I set :prepend on a build hook, the compiler seems to ignore it and compile the js with the previous value of :prepend. So if itā€™s unset, nothing is prepended. If itā€™s some value, itā€™ll be that value. Is this use case explicitly unsupported by build hooks?

thheller13:11:26

where do you set the :prepend? likely just in the wrong place

levitanong13:11:43

@thheller (assoc-in build-state [:shadow.build/config :modules :main :prepend] licenses)

thheller13:11:13

and in which stage?

levitanong13:11:50

Iā€™ve tried it in both :configure and :compile-prepare

levitanong13:11:56

neither seems to work

thheller13:11:19

right. hooks run after the original code

thheller13:11:37

so the :configure stage will already configure the modules

thheller13:11:11

so to adjust the config after the fact you have to dig a bit deeper

thheller13:11:42

or actually not that deep

levitanong13:11:54

So before this, Iā€™ve been running a tools deps alias, modifying the config before calling release

thheller13:11:03

(assoc-in build-state [:shadow.build.modules/modules :main :prepend] licenses)

levitanong13:11:17

oh! iā€™ll try that šŸ˜„

thheller13:11:02

:prepend-js would be a bit more complicated but :prepend should work like that

thheller13:11:23

maybe try update-in, just so it doesn't overwrite if something is already there

levitanong13:11:42

@thheller doesnā€™t work yet šŸ˜ž

levitanong13:11:38

Could it be :shadow.build.closure/modules?

thheller13:11:45

this is a :browser target right?

thheller13:11:51

closure modules shouldn't be there yet?

thheller13:11:10

thats after optimizations

thheller13:11:03

:shadow.build.closure/modules is a copy of :shadow.build.modules/modules after optimizations. since that can adjust things

thheller13:11:21

oh wait .. it is the :build-modules

thheller13:11:37

which is a sorted vector of the modules

thheller13:11:50

damn there are really too many places modules is used. should clean that up.

thheller13:11:08

(assoc-in build-state [:build-modules 0 :prepend] licenses)

levitanong13:11:18

thereā€™s also a :shadow.build.modules/config with similar looking stuff šŸ˜„

levitanong13:11:33

oof, modifying a vector index is a little scary

thheller13:11:56

well you can find it by :module-id

thheller13:11:49

but 0 will always be the first base module with no dependencies

levitanong13:11:32

trying it out

thheller13:11:40

just don't change the order or things will go bad šŸ˜›

levitanong13:11:33

I tried (assoc-in build-state [:build-modules 0 :prepend] licenses) and it still doesnā€™t work. I ran (keys build-state) and I canā€™t find any :build-modules in the list. Could it be that my version is too old? Iā€™m on 2.8.66, and when i checked the recent commits, there was nothing that jumped out at me that signaled that i needed to update.

thheller13:11:54

no that hasn't changed in years

thheller13:11:57

which stage?

thheller13:11:55

try :compile-prepare

thheller13:11:11

module config is actually done after configure. so :shadow.build.modules/config should have worked?

thheller13:11:41

oh doh .. I gave you the wrong key I think. should be :shadow.build.modules/config not :shadow.build.modules/modules

thheller13:11:22

yeah definnitely too many places where that config is kept šŸ˜›

levitanong13:11:18

hahaha this is hilarious.

levitanong13:11:43

Okay, so :build-modules works in :compile-prepare. Will try it out in :shadow.build.modules/config now

thheller13:11:25

it goes from the build config -> :shadow.build.modules/config. then after configure they are sorted and :build-modules is created (no longer a map)

thheller13:11:49

optimize takes :build-modules and creates :shadow.build.closure/modules (including some of the GCC compiler data) otherwise the same

thheller13:11:17

:flush then takes either of those keys to flush the output but :prepend must be set before so it doesn't mess with the source maps

thheller13:11:13

so is must happen before :optimize-prepare

levitanong13:11:11

That does feel quite convoluted šŸ˜…

coder4633413:11:33

Hi! When I start shadow-cljs with :browser-test , insead of :app, my spec instrumentation doesn't work. The specs work with (exercise fully-qualified-ns/spec), but I can't instrument functions either through code or repl. Any ideas? I don't even know where to look

levitanong13:11:40

@thheller okay, can confirm, :shadow.build.modules/config works when i do it in :configure

šŸ‘ 4
levitanong13:11:44

@thheller thanks for the help!

devirr16:11:13

@publicz try version 2.8.60. instrument and check works for me on that version. but when I upgrade it does not.

coder4633414:11:44

Thanks, I'll try!

thheller16:11:10

what is the particular problem with instrument? I never use it myself but I'm not aware of anything that would have changed its behavior since 2.8.60?

mruzekw16:11:23

I have a :node-library that Iā€™d like to play with in a REPL, but Iā€™m unsure how to load it

thheller16:11:04

most likely shadow-cljs node-repl is good enough

mruzekw17:11:17

I used that command, but when I (require 'myapp.backend.parser) It says it canā€™t find it

thheller17:11:40

what does it say exactly?

mruzekw17:11:53

{:type clojure.lang.ExceptionInfo
   :message "The required namespace \"myapp.backend.parser\" is not available, it was required by \"cljs/user.cljs\"."
   :data {:tag :shadow.build.resolve/missing-ns,

thheller17:11:18

and that namespace does actually exist?

thheller17:11:43

ie. :source-paths ["src/main"] and src/main/myapp/backend/parser.cljs

thheller17:11:12

(or whatever setup you use for managing :source-paths)

mruzekw17:11:27

Ughā€¦the file is where it should be but I didnā€™t name the namespace correctly in the actual file :man-facepalming:

wilkerlucio18:11:29

trying to start a new project here, using deps, but for reason I'm getting

Could not locate shadow/cljs/devtools/cli__init.class, shadow/cljs/devtools/cli.clj or shadow/cljs/devtools/cli.cljc on classpath.

wilkerlucio18:11:46

shadow 2.8.69

lilactown18:11:00

add thheller/shadow-cljs to your deps

wilkerlucio18:11:21

is this a new thing? I'm looking at old projects, it wasnt needed before

lilactown18:11:23

the npm module no longer adds itself to the classpath if youā€™re using deps.edn or leiningen

lilactown18:11:41

yes, I think it was added in 2.8.60 or around there

nickmbailey18:11:41

@thheller i got the export metadata addition working with a macro btw. thanks for the help

nickmbailey18:11:18

does the googe closure compilation eliminate unused code from clojurescript core too?

devirr19:11:58

@thheller I got an require error on versions 2.8.61 and 2.8.64 (:target :node-script) when running cljs.spec.test.alpha/check but just tried on 2.8.69 and it works again. Sorry for the inconvenience

raf22:11:23

hi there! first of all - thanks @thheller for the shadow-cljs - this tool makes working with ClojureScript a pleasure! second, I have some wired behavior when I start shadow-cljs from VS Code (and Calva). At first everything look OK, source code compile, server is starting (and I can see my app), but then when I change my file and save it I get such error message in the terminal: `Evaluating file: fire.cljs no source by id: [:shadow.build.classpath/resource "project/fire.cljs"] {:id [:shadow.build.classpath/resource "project/fire.cljs"]} ExceptionInfo: no source by id: [:shadow.build.classpath/resource "project/fire.cljs"] shadow.build.data/get-source-by-id (data.clj:167) shadow.build.data/get-source-by-id (data.clj:164) shadow.build.compiler/remove-dead-js-deps/remove-fn--12063/fn--12064 (compiler.clj:1089) clojure.core/complement/fn--5669 (core.clj:1441) clojure.core/filter/fn--5893 (core.clj:2817) clojure.lang.LazySeq.sval (LazySeq.java:42) clojure.lang.LazySeq.seq (LazySeq.java:51) clojure.lang.ChunkedCons.chunkedNext (ChunkedCons.java:59) clojure.core/chunk-next (core.clj:708) clojure.core.protocols/fn--8154 (protocols.clj:137) clojure.core.protocols/fn--8154 (protocols.clj:124) clojure.core.protocols/fn--8114/G--8109--8123 (protocols.clj:19) clojure.core.protocols/seq-reduce (protocols.clj:31) clojure.core.protocols/fn--8146 (protocols.clj:75) clojure.core.protocols/fn--8146 (protocols.clj:75) clojure.core.protocols/fn--8088/G--8083--8101 (protocols.clj:13) clojure.core/reduce (core.clj:6828) clojure.core/into (core.clj:6895) clojure.core/into (core.clj:6887) shadow.build.compiler/remove-dead-js-deps/remove-fn--12063 (compiler.clj:1091) clojure.core/update (core.clj:6196) clojure.core/update (core.clj:6188) shadow.build.compiler/remove-dead-js-deps/fn--12068/fn--12069 (compiler.clj:1097) clojure.core/map/fn--5866 (core.clj:2753) clojure.lang.LazySeq.sval (LazySeq.java:42) clojure.lang.LazySeq.seq (LazySeq.java:51) clojure.lang.RT.seq (RT.java:535) clojure.core/seq--5402 (core.clj:137) clojure.core.protocols/seq-reduce (protocols.clj:24) clojure.core.protocols/fn--8146 (protocols.clj:75) clojure.core.protocols/fn--8146 (protocols.clj:75) clojure.core.protocols/fn--8088/G--8083--8101 (protocols.clj:13) clojure.core/reduce (core.clj:6828) clojure.core/into (core.clj:6895) clojure.core/into (core.clj:6887) shadow.build.compiler/remove-dead-js-deps/fn--12068 (compiler.clj:1098) clojure.core/update (core.clj:6196) clojure.core/update (core.clj:6188) shadow.build.compiler/remove-dead-js-deps (compiler.clj:1095) shadow.build.compiler/remove-dead-js-deps (compiler.clj:1084) shadow.build.compiler/compile-all (compiler.clj:1347) shadow.build.compiler/compile-all (compiler.clj:1194) shadow.build.api/compile-sources (api.clj:256) shadow.build.api/compile-sources (api.clj:248) shadow.build.api/compile-sources (api.clj:260) shadow.build.api/compile-sources (api.clj:248) shadow.cljs.repl/repl-load-file* (repl.clj:292) shadow.cljs.repl/repl-load-file* (repl.clj:232) shadow.cljs.devtools.server.worker.impl/do-repl-rpc (impl.clj:832) shadow.cljs.devtools.server.worker.impl/do-repl-rpc (impl.clj:792) shadow.cljs.devtools.server.worker.impl/fn--13594 (impl.clj:876) shadow.cljs.devtools.server.worker.impl/fn--13594 (impl.clj:875) clojure.lang.MultiFn.invoke (MultiFn.java:234) shadow.cljs.devtools.server.util/server-thread/fn--13177/fn--13178/fn--13186 (util.clj:285) shadow.cljs.devtools.server.util/server-thread/fn--13177/fn--13178 (util.clj:284) shadow.cljs.devtools.server.util/server-thread/fn--13177 (util.clj:257) java.lang.Thread.run (Thread.java:834)` any ideas what am I doing wrong?

raf22:11:09

I use the :browser target with only shadow-cljs.edn file (without lein)

Drew Verlee00:11:00

what does your shadow-cljs.edn file look like?

Drew Verlee00:11:36

I feel this is a classpath or organizational issue. As in, maybe the build-id of the app isn't what your telling your repl to look for.

raf07:11:00

Hello šŸ™‚

raf07:11:57

the shadow-cljs.edn looks so:

raf07:11:58

{:source-paths ["src/dev" "src/main" "src/functions" "src/tools" "src/test"] :dependencies [[binaryage/devtools "0.9.10"] [reagent "0.8.1" :exclusions [cljsjs/react]] [re-frame "0.10.9" :exclusions [cljsjs/react]] ; [day8.re-frame/http-fx "v0.2.0"] [secretary "1.2.3"] [cljs-bean "1.5.0"] ;;https://github.com/mfikes/cljs-bean [cider/cider-nrepl "0.22.4"] [testdouble/clojurescript.csv "0.4.5"] ] ; :nrepl {:port 8777} :builds {:app {:target :browser :output-dir "public/js" :asset-path "/js" :modules {:app {:init-fn project.core/init :preloads [devtools.preload]}} :devtools {:http-root "public" :http-port 8000}} :browser-test {:target :browser-test :ns-regexp "-test$" :runner-ns shadow.test.browser :test-dir "tests/browser-test" :devtools {:http-root "target/browser-test" :http-port 8290}} :karma-test {:target :karma :ns-regexp "-test$" :output-to "tests/karma-test.js"} :functions {:target :node-library :output-to "functions/cljs-libs.js" :exports-var project.cloud-functions/declaration} :tools {:target :node-script :output-to "tools/tools.js" :main project.tools/main}}}