Fork me on GitHub
#shadow-cljs
<
2022-05-31
>
dvingo13:05:28

Hi Thomas, in the context of Malli function instrumentation. I'm wondering if there is a way to tell the compiler, not only to always recompile a namespace (with {:dev/always true}), but also to instruct the compiler to do so after all other namespaces - without needing a solution like you mentioned here https://clojureverse.org/t/problem-using-malli-clojurescript-instrumentation-and-shadow-cljs/8612/2 of explicitly including every namespace that you want to compile before the entry one (or preload). The dream setup would be adding one piece of metadata to the entry namespace (for a webapp) and then getting repl friendly instrumentation. Not sure if this is possible, so wanted your opinion on the matter. Thanks.

thheller13:05:45

define "repl friendly instrumentation"? the hot-reload cycle is entirely independent of the REPL so that confuses me?

dvingo13:05:48

Ah you're right - it's really just hot-reload - making sure the changes in leaf namespaces (changing the malli schema used by a function) is picked up in the entry namespace. Here's the setup for instrumenting with fn metadata: 1. in your entry namespace in your after-load callback the user invokes a macro () this scans all namespaces and collects any functions that have :malli/schema metadata 2. In your leaf namespace like my.app.utils you have a function like:

(defn minus-small-int
  {:malli/schema [:=> [:cat :int] small-int]
   :malli/scope  #{:input :output}}
  [x] (dec x))
3. I'm dev'ing this function and changing the schema and the implementation The workflow I want is to just edit the leaf namespace and have the () call get macro-expanded and compiled + eval'd again with this new schema. I'm also open to other suggestions about how to achieve this - maybe an editor command to submit that macro call? then your workflow is: save file. invoke editor command. ?

thheller13:05:24

what you can do if abuse the after-load hook a little bit

thheller13:05:09

(defn ^:dev/after-load malli-instrument []
  (js/cljs-eval "(malli.dev/start!)"))

thheller13:05:04

that basically just evals () after every hot-reload

thheller13:05:29

no clue how that behaves if it gets called after every compile though

thheller13:05:44

might not like getting started several times

thheller13:05:55

or might just do a lot of work that is unnecessary and as such slow everything else down

dvingo13:05:50

oh very cool! Well at least it pushes the problem from a staleness one to a perf one. Is there a way in a macro to determine which namespaces have changed (provided by some compiler data?) that way I don't have to scan every ns

thheller13:05:04

in a macro not really no

thheller13:05:57

I mean strictly speaking yes but that would be shadow-cljs only and even then not guaranteed to be reliable

thheller13:05:11

has to account for cache and stuff

dvingo13:05:10

got it - would it be really bad to use the ns to lookup its file modified time ? that way I could store some state to keep track which ns's changed

dvingo13:05:19

or maybe hash the namespace object?

thheller13:05:23

sure thats one option

dvingo14:05:24

ok great! thanks so much for the help

isaackarth15:05:15

I've gotten curious about the current best way to do documentation generation. Many of the previous ways to do this (Marginalia, Codox, Dynadoc) seem to mostly be via lein plugins (or deps.edn). What's the best way to generate docs with Shadow? (Or is everyone just using cljdoc?)

thheller15:05:23

anything that works with deps.edn should also work with shadow

thheller16:05:15

or just use lein with the plugins. they are all seperate tools that don't require shadow-cljs in any way to work

Emile Snyder17:05:24

Hi all, I'm new here. I've got a question about problems compiling with shadow-cljs for a project using Fabric.js. We're currently trying to upgrade a bunch of packages; we are building ok pre-upgrade. As I understand it, fabric is using jsdom. On lein shadow compile app we're seeing a whole bunch of errors like:

[:app] Compiling ...
Closure compilation failed with 20 errors
--- node_modules/jsdom/lib/jsdom/living/generated/AbortSignal.js:95
constructor is missing a call to super()
--- node_modules/jsdom/lib/jsdom/living/generated/Attr.js:96
constructor is missing a call to super()
--- node_modules/jsdom/lib/jsdom/living/generated/CDATASection.js:94
constructor is missing a call to super() 
Googling I see this one question/answer in 2019 (https://clojurians-log.clojureverse.org/shadow-cljs/2021-08-13) to a similar constructor is missing a call to super() error, but I'm not sure where to go from here. Any advice welcome!

thheller17:05:50

@emile what are you building? looks like it might be a browser build? jsdom is intended for node envs? what is your build :target?

thheller17:05:46

jsdom shouldn't be included for browser builds?

Emile Snyder17:05:10

@thheller yes, :target is :browser. We have a clojurescript reframe component that uses Fabric.js and canvas element to let you draw various regions on top of an image, then turn what you've drawn into svg. Fabric is apparently using jsdom. Are you saying this should never have worked? 🙂

thheller17:05:47

no, I'm saying jsdom shouldn't be included

thheller17:05:10

it appears to be an optional dependency. so something you have done must lead to its inclusion. not sure what

thheller17:05:16

what shadow-cljs version do you use?

thheller17:05:26

anything special in your build config?

thheller17:05:34

do you directly require jsdom somewhere?

Emile Snyder17:05:39

You'll have to forgive me, my grasp of dealing with dependency stuff is not strong. We are trying to upgrade a bunch of stuff, including shadow-cljs to 2.19.0 from 2.11.18. I'm trying to figure out what's pulling in jsdom now...

thheller18:05:16

maybe that update is enough

thheller18:05:58

hmm I can reproduce this. let me look

Emile Snyder18:05:32

@thheller re: jsdom as optional dependency of fabric... our team is confused 🙂 We can't find anything explicit in our dependencies for jsdom. When we remove package-lock.json , run npm install --no-optional and then lein shadow compile app we see:

[:app] Compiling ...
The required JS dependency "jsdom" is not available, it was required by "node_modules/fabric/dist/fabric.js".

Dependency Trace:
	mobot_web/app.cljs
	mobot_web/core.cljs
	mobot_web/admin/views/core.cljs
	mobot_web/admin/views/test_plan_runner.cljs
	mobot_web/admin/views/components/assessment_region_editor.cljs
	node_modules/fabric/dist/fabric.js

Searched for npm packages in:
	/home/emile/dev/mobot-doc-change/mobot-web/node_modules

See: 

thheller18:05:56

the problem is in fabric, not your code

thheller18:05:21

it is trying to include jsdom conditionally in a way that shadow-cljs does not recognize properly. so it ends up trying to include it fully

thheller18:05:24

I'm checking why

thheller18:05:07

you can set this is :js-options in your build config

:resolve {"jsdom" false
              "jsdom/lib/jsdom/living/generated/utils" false
              "jsdom/lib/jsdom/utils" false}

🙏 4
thheller18:05:14

that'll fix it for now

Emile Snyder18:05:45

Much appreciated!

dpsutton18:05:14

We lightly use shadow-cljs at work but this interaction here is an example of exactly why I keep my sponsorship of @thheller on github. Incredible

🙌 4
💯 8
1
1
❤️ 1