Fork me on GitHub
#shadow-cljs
<
2022-07-27
>
mkvlr07:07:12

when requring a https://shadow-cljs.github.io/docs/UsersGuide.html#classpath-js file, it doesn’t trigger a rebuild when I change it or detect changes to this file when I trigger a recompile by changing the requiring cljs file. Is this expected and is there a workaround?

thheller07:07:41

it should? works for me

thheller07:07:09

although it doesn't work for commonjs files probably? do you use ES modules (import/export) or commonjs?

thheller07:07:07

hmm nope also works for commonjs, although somewhat limited by design given its commonjs

thheller07:07:16

but it definitely watchs and triggers recompiles

mkvlr07:07:05

trying to turn it on & off again…

thheller07:07:06

which version do you use? I tried with master, can't remember if there was something broken related to this in earlier versions maybe?

thheller07:07:12

hmm yeah that should be fine. definitely didn't change anything recently

mkvlr07:07:35

should I try a bump anyway?

mkvlr07:07:49

I’ll also try a minimal repro

thheller07:07:50

> it doesn’t trigger a rebuild when I change it or detect changes to this file when I trigger a recompile by changing the requiring cljs file.

thheller07:07:54

the first part I checked

thheller07:07:14

the second part confuses me? changing the requiring cljs file will recompile the js file?

thheller07:07:36

or do you mean a CLJS file required by the JS? I did not test that

mkvlr08:07:55

no, I mean that when I trigger a recompile of the file requiring my js file (the file that has (:require ["/barcode-detector-zbar/BarcodeDetector.js$default" :as barcode-detector-polyfill]) in it, I don’t see changes to the js file

thheller08:07:32

I'm confused. what changes would you see in the JS file if you modify the CLJS file?

mkvlr08:07:16

I modify both

mkvlr08:07:25

so when I just modify the js, nothing happens

thheller08:07:48

ok, thats the relevant bit. it should reload just fine, regardless of what you do to the CLJS file

thheller08:07:08

and changing the CLJS file should have no effect on what the JS files does whatsoever, so that is working as expected I guess

thheller08:07:46

I just tried by adding a console.log to the JS file and changing that log. works fine. but I dunno what else you might be doing?

mkvlr08:07:11

aha, I now moved my js from resources to src and now it works

mkvlr08:07:54

using :deps with shadow, but resources in on the classpath brought in by the root deps declaration

thheller08:07:47

oh yeah, resources are filtered out because many people put their outputs into resources/public and watching the resources folder thus becomes very noisy and expensive

mkvlr08:07:26

good to know, thanks!

mkvlr09:07:34

now running into Uncaught TypeError: gaa.default.setupPolyfill is not a function in advanced. Externs should be inferred automatically with :compiler-options {:infer-externs :auto}, is that correct?

borkdude09:07:35

I've posted a question/issue about target esm https://github.com/borkdude/cherry/issues/24 but feel free to discuss it here as well 🧵

👀 1
borkdude09:07:25

The context:

cherry-cljs/cljs.core.js
is a target esm-built .js file with core functions. It has e.g. js-keys which AFAIK doesn't depend on any other core function, so when only importing that, I'd expect that the tree-shaken build of a JS file, would be rather small.

thheller09:07:05

what do you mean by "only importing"? shadow-cljs can only see what you configured and keeps all that stuff alive

thheller09:07:22

what you import the closure compiler cannot see?

thheller09:07:37

oh nvm. didn't see the link. answering there

borkdude10:07:53

Thanks for your comment. I suspected something like that

bbss09:07:50

I've just posted a question/issue about an as of yet non-existing :target :jupyter https://github.com/thheller/shadow-cljs/issues/1039. But am also on slack 👋

bbss09:07:34

As said there perhaps :esm would also be helpful for me 🙂

borkdude09:07:27

Target :esm solves everything :) - Have you tried it @bbss?

bbss09:07:44

Yes, I've tried it but ran into some issues with it sadly. The target that got me furthest so far is :npm-module, but that doesn't seem to inject the repl, unacceptable!

mkvlr09:07:02

https://shadow-cljs.github.io/docs/UsersGuide.html#_simplified_externs is the name / location fixed and I can’t put it elsewhere and reference it via :compiler-options :externs?

thheller09:07:05

@mkvlr externs inference only covers CLJS files, no inference is done for JS files. yes, there are no options to configure the simplified externs

👍 1
thheller09:07:48

@bbss to get a REPL for :npm-module builds you just need to require the REPL client ns *from* javascript somewhere. so something like if (process.env.NODE_ENV === "development") { require("./path-to-cljs/shadow.cljs.devtools.client.browser"); } or so

bbss09:07:34

Okay, good to know that should work! I think I am probably a special case for npm-module though, since eventually jupyter notebook extensions run in the browser anyway..

thheller09:07:16

thats no problem. the issue is just that the :npm-module build doesn't have a clearly defined "entry" point

thheller09:07:35

:browser and the others do so shadow-cljs can ensure that the devtools client is loaded before those

thheller09:07:51

for npm-module that is not the case because it can't tell which file you are going to access from JS

bbss10:07:19

Could that also be why I ran into ReferenceError: shadow$provide is not defined

thheller10:07:06

:npm-module doesn't use shadow$provide unless you specifically configure it? or was that :target :browser?

thheller10:07:37

I'll answer your issue in more detail later

👍 1
bbss10:07:34

That was with :npm-module iirc :thinking_face:

bbss10:07:51

Okay, thanks!

thheller10:07:15

@bbss what would help if you setup a repo with stuff that does not work! much easier to look at an actual failing thing than just guessing

thheller10:07:34

I have never used jupyter so I'm not sure I can even get that running

thheller10:07:49

so just if (process.env.NODE_ENV === "development") { require("./lib/shadow.cljs.devtools.client.browser"); }

thheller10:07:04

but yeah it would probably be easier with :target :esm

thheller10:07:10

I'll answer more later. gotta go 🙂

bbss10:07:47

Okay, will make a repro case for the failing import, thank you.

ag18:07:12

Is there a way to run shadow-cljs clj-repl and immediately execute some code in it? Right now, I'm having to do: clojure -M:dev:shadow-cljs clj-repl, and then inside the repl I have to type (integrant.repl/go). Can I do it in a single line? I've been trying to combine clj-eval and clj-repl options, but that doesn't seem to work.

thheller19:07:18

do you actually intend to use the REPL provided by clj-repl or do you just leave that running and connect via nrepl or so?

ag19:07:37

Hmmm. I haven't thought about it. What would be the difference? Would there be something blocking?

thheller19:07:19

no the answer just becomes more complicated 😉

thheller19:07:12

basically you create a (defn start {:shadow/requires-server true} [] (integrant.repl/go)) and shadow-cljs run that.ns/start

thheller19:07:36

with a proper ns form with requires of course

ag19:07:01

Oh, that's interesting. Let me try it out. I feel I'd have to come back with some more questions. Thank you Thomas.

Drew Verlee19:07:38

does shadow only consider the deps in the aliases passed to shadow-cljs.edn's :dep's key? e.g will i get foo and bar in this setup or just bar?

shadow-cljs.edn
:deps ["cljs"]


and my deps files

:deps {foo ...} :aliases {:cljs {:extra-deps {bar ....}

thheller19:07:55

:deps ["cljs"] does not activate any aliases :deps {:aliases [:cljs]} does

Drew Verlee19:07:26

are the extra-deps in the aliases in addition to the ones in the deps :deps key?

Drew Verlee19:07:33

ty ty. I was just setting up a project to test it. 🙂

ag19:07:59

what's the current stable version of shadow-cljs? I just tried upgrading to 2.19.8, but I'm getting Exception in thread "main" Syntax error compiling at (shadow/build/data.clj:362:5)... something that seems to be related to clojure.lang.Compiler.analyze. Do I miss an exclusion?

thheller19:07:02

whats the full error? 2.19.8 is the latest yes

ag19:07:07

this is the content of deps.edn, maybe you can spot something I don't.

{:paths ["src" "resources"]
 :deps
 {org.clojure/clojure        {:mvn/version "1.11.1"}
  integrant/integrant        {:mvn/version "0.8.0"}
  ring/ring-core             {:mvn/version "1.9.5"}
  ring/ring-jetty-adapter    {:mvn/version "1.9.5"}
  metosin/reitit             {:mvn/version "0.5.17"}
  hiccup/hiccup              {:mvn/version "2.0.0-alpha2"}
  org.clojure/tools.logging  {:mvn/version "1.2.4"}
  org.slf4j/log4j-over-slf4j {:mvn/version "2.0.0-alpha7"}
  org.slf4j/slf4j-jdk14      {:mvn/version "2.0.0-alpha7"}
  org.clojure/tools.cli      {:mvn/version "1.0.206"}

  ;; front-end
  org.clojure/clojurescript     {:mvn/version "1.11.4"}
  reagent/reagent               {:mvn/version "1.1.1"}
  re-frame/re-frame             {:mvn/version "1.3.0-rc3"}
  cljs-bean/cljs-bean           {:mvn/version "1.8.0"}
  day8.re-frame/http-fx         {:mvn/version "0.2.4"
                                 :exclusions  [commons-logging/commons-logging]}
  day8.re-frame/test            {:mvn/version "0.1.5"}
  hickory/hickory               {:mvn/version "0.7.1"}
  metosin/reitit-frontend       {:mvn/version "0.5.17"}
  metosin/reitit-schema         {:mvn/version "0.5.17"}
  re-frame-utils/re-frame-utils {:mvn/version "0.1.0"}
  inflections/inflections       {:mvn/version "0.13.2"}}

 :aliases
 {:shadow-cljs
  {:extra-paths ["test"]
   :extra-deps {thheller/shadow-cljs {:mvn/version "2.19.8"}}
   :main-opts ["-m" "shadow.cljs.devtools.cli"]}

  :dev
  {:extra-paths ["dev"]
   :extra-deps
   {integrant/repl {:mvn/version "0.3.2"}}}

  :test
  {:extra-paths ["test"]
   :extra-deps {io.github.cognitect-labs/test-runner
                {:git/tag "v0.5.0" :git/sha "b3fd0d2"}}
   :main-opts ["-m" "cognitect.test-runner"]
   :exec-fn cognitect.test-runner.api/test}

  :build
  {:extra-paths ["src"]
   :extra-deps {io.github.clojure/tools.build
                {:git/tag "v0.8.1" :git/sha "7d40500"}}
   :ns-default build}

  :cider-cljs {:main-opts
               ["-m" "nrepl.cmdline" "--middleware"
                "[cider.nrepl/cider-middleware,cider.piggieback/wrap-cljs-repl]"]}}}

ag19:07:47

I'm reinstalling npm packages and trying 2.19.8, again

thheller19:07:48

definitely remove clojurescript or bump it to 1.11.60

thheller19:07:29

otherwise looks fine

ag19:07:02

yeah, I think that was it. OMG, thank you so much.

thheller19:07:02

that line is using commons-codec? I guess you maybe have that excluded somewhere when it shouldn't be?

thheller19:07:09

it has also been there for years 😉

ag19:07:49

I'm sorry, I have yet another one: when I'm in the repl and I run shadow.cljs.devtools.api/nrepl-select:app`, it complains :missing-nrepl-middleware. Do I need to add piggieback? I thought you don't have to when using deps.edn with shadow-cljs, no?

thheller20:07:05

if you run your own nrepl server you need to add the proper nrepl middleware

thheller20:07:31

I guess in your :cider-cljs alias?

thheller20:07:54

or just use the nrepl server provided by shadow-cljs and don't launch your own 😉

ag20:07:17

I have added :repl-options {:init-ns user into :shadow-cljs alias, now when I run clojure -M:dev:shadow-cljs clj-repl, should I expect it to land me in user ns? Because it doesn't. It still starts in shadow.user

thheller20:07:43

no, that does nothing. nrepl doesn't look there. that was a lein specific config option

👍 1
thheller20:07:01

you can set :repl {:init-ns user} in shadow-cljs.edn at the top level. but that again would only affect the nrepl server started by shadow-cljs? which I guess you don't actually use?

thheller20:07:09

I'm a bit confused by your setup 😉

ag20:07:51

Yes, it looks like I don't need :cider-cljs alias. with that :repl-options config you mentioned earlier.

ag20:07:00

On slightly unrelated note, I'm getting these, btw:

------ WARNING #1 - :redef -----------------------------------------------------
 Resource: no/en/core.cljc:137:1
--------------------------------------------------------------------------------
 134 |   [s]
 135 |   (parse-number s #(#?(:clj Integer/parseInt :cljs js/parseInt) %1)))
 136 | 
 137 | (defn parse-long
-------^------------------------------------------------------------------------
 parse-long already refers to: cljs.core/parse-long being replaced by: no.en.core/parse-long
--------------------------------------------------------------------------------
...

thheller20:07:33

upgrade noencore

ag20:07:06

yes, it seems from inflections. Sorry. I thought it's somehow related to me bumping Cljs. Apologies for the noise.

ag20:07:48

right, bumping it fixed it. I blame my OCD. I should learn to be more patient and learn how to read the error messages.

mkvlr21:07:25

I put up a https://github.com/mk/shadow-barcode-wasm#attempt-to-use-barcode-detector-zbar-with-shadow-cljs. Would appreciate any pointers of other things I could try to get this working.

thheller21:07:13

do you have this file not-minified?

thheller21:07:39

really no point in using the minified file here, shadow-cljs will minify it anyways

mkvlr21:07:57

yes, but I can’t use it because it loads a wasm dep using webpack magic

mkvlr21:07:15

shadow will complain that it can’t load wasm, sec grabbing the error

mkvlr21:07:27

Failed to inspect file
  /Users/mk/dev/shadow-barcode/node_modules/zbar.wasm/dist/zbar.wasm.bin

it was required from
  /Users/mk/dev/shadow-barcode/node_modules/zbar.wasm/dist/load-browser.js

Errors encountered while trying to parse file
  /Users/mk/dev/shadow-barcode/node_modules/zbar.wasm/dist/zbar.wasm.bin
  {:line 1, :column 0, :message "Character '' (U+0000) is not a valid identifier start char"}

thheller21:07:37

yeah, I was just confused why the minified file doesn't do that

thheller21:07:48

but I guess thats a file built by webpack already

mkvlr21:07:55

I think this is webpack load-file rewriting it

thheller21:07:12

ok yeah this will be no fun. you'll basically need to add a gazillion externs

mkvlr21:07:44

oh, against everything in this minified file?

thheller21:07:36

well, against all the imports the JS passes to the wasm

thheller21:07:40

and the exports it gets from the wasm

thheller21:07:07

I cannot even guess what those are given the minified nature of the file

thheller21:07:32

you can try :simple I guess?

mkvlr21:07:40

hmm, is there another way if I write code directly against zbar.wasm?

mkvlr21:07:02

because this wrapper lib isn’t a lot of code

thheller21:07:07

those are the imports passed to the wasm file. :advanced was renaming all of them, so I changed imports.wbg.* to imports["wbg"]["..."] instead

thheller21:07:11

which protects it from renaming

mkvlr21:07:40

re simple: I guess if there’d be a way to only use simple for this js module, the bundle size impact would be basically zero

thheller21:07:45

I cannot tell what the min file is doing, but it must construct such an object somewhere

thheller21:07:30

I mean just include the file separately? why does it need to be part of your build?

mkvlr21:07:00

hmm, I started with that, why the hell did I go so off the rails 🙈

mkvlr21:07:02

so load it via a script tag?

thheller21:07:51

well if you use :target :esm you can also load it via (:require ["esm:./BarcodeDetectorPolyfill.min.js$default" :as barcode-detector-polyfill])

thheller21:07:08

and putting the file into the same folder as the shadow-cljs output

thheller21:07:28

so it just does a runtime import since it already is a ES module

mkvlr21:07:15

huh, that sounds nice, then I have more control over the loading

thheller21:07:19

esm: just tells shadow-cljs to do a runtime import instead of a build time import

mkvlr21:07:54

so you recommend esm these days for cases like this or do you still expect rough edges?

thheller21:07:37

(that might also work with :target :browser I guess)

thheller21:07:58

I haven't worked on :esm much but there isn't much to work on. it seems to work fine.

thheller21:07:19

only recommending it because of ESM interop with ESM works well

thheller21:07:32

non-ESM with ESM not so much, although dynamic import may just work

thheller21:07:42

hmm no it won't I guess

thheller21:07:09

(due to closure compiler rewriting import() still I think, something regarding that broke)

mkvlr21:07:55

yeah, getting main.js:1425 ReferenceError: shadow_esm_import is not defined with dyanamic import

mkvlr21:07:43

trying esm now

thheller21:07:47

set :prepend "function shadow_esm_import(name) { return import(name) }" to your build :modules config

thheller21:07:12

so next to :entries

thheller21:07:03

or just a <script> tag in the page also works

mkvlr21:07:04

ah nice, so I can load it now, now last thing I need is get to the $default thing

thheller21:07:41

just (.-default mod)?

mkvlr22:07:43

yeah, that works for getting functions, to create an instance I’m doing (.construct js/Reflect (.-default polyfill-module) #js []) or is there an easier way?

mkvlr22:07:56

but everything is working now, this is great, thanks so much for your help

thheller22:07:00

why reflect?

thheller22:07:28

(new (.-default polyfill-module))?

mkvlr22:07:12

because I didn’t know this was a thing, doh

mkvlr22:07:01

well this is nice & compact now, thanks again

(-> (dynamic-import "/barcode-detector-zbar/BarcodeDetectorPolyfill.min.js")
    (.then (fn [^js mod]
             (let [$default (.-default mod)]
               (js/console.log "native api support:" (.checkBarcodeDetectorSupport $default))
               (.setupPolyfill $default)
               (doto (new $default)
                 (js/console.log))))))

👍 1
mkvlr22:07:48

cool, can confirm advanced is now working too

thheller22:07:06

(js-await [^js mod (dynamic-import "/barcode-detector-zbar/BarcodeDetectorPolyfill.min.js")]
  (let [$default (.-default mod)]
    (js/console.log "native api support:" (.checkBarcodeDetectorSupport $default))
    (.setupPolyfill $default)
    (doto (new $default)
      (js/console.log))))

👍 1
mkvlr22:07:32

where is that defined?

mkvlr22:07:51

ah I see [shadow.cljs.modern :refer (js-await)]

colliderwriter23:07:57

is there an approved way to get out-of-tree source files into shadow-cljs :paths ? i have some cljc i need to share between front and back ends. I get a warning when i try

:paths ["../../components" "src"]