Fork me on GitHub
#shadow-cljs
<
2023-01-02
>
michihuber10:01:09

Happy New Year! 🎆 I'm seeing an issue where I've meta'd all the externs inference warnings, but the build is broken because of un-externed names. Any input on how I can debug this?

michihuber10:01:41

Previously, we've used lein extern to generate them, and if I run that and include those externs in the build, its all fine.

michihuber10:01:13

Otherwise I get "Uncaught Module not provided: 10"

michihuber10:01:14

(I now always get that error, can't get the app to launch anymore.)

thheller13:01:40

you can create a release build with npx shadow-cljs release app --pseudo-names. that usually makes it easy to track what was renamed and which externs you would need.

thheller13:01:14

don't know what you are doing exactly so can't provide more tips

thheller13:01:53

the module not provided I'm guessing you get from either some bad cache or trying to mix files from different builds?

thheller13:01:23

or are there maybe other errors, before or after which may lead to this one?

michihuber14:01:01

hm, so building with --pseudo-names fixes it

michihuber14:01:05

any idea how to proceed from there?

thheller15:01:41

do you use clj->js or js->clj alot?

thheller15:01:20

pseuo-names really shouldn't fix anything. if it does it likely means that the conflict is on a very short property name

thheller15:01:34

the closure compiler shortens things to .a .b etc frequently

thheller15:01:52

with pseudo-names that becomes .$whateverItWasBefore$

thheller15:01:59

which is less likely to cause conflicts

thheller15:01:16

the only known issue I'm aware of regarding this is with js->clj

thheller15:01:00

what kind of externs did you have before? I don't know that lein extern is so dunno what that generaetd

michihuber15:01:09

I do use clj->js and vice versa, not sure if a lot, but I think not

michihuber15:01:13

when does this become an issue?

michihuber15:01:41

one issue I just saw:

(.on win "close" #(do
                            (.set Settings "winBounds" (.getBounds win))
                            (when-not (contains? @!can-close window-id)
                              (.preventDefault %)
                              (async/put! event-queue
                                          {:window-id window-id
                                           :payload [:window/close-requested]}))))
this is code from an integrant init-key defmethod and doesn't produce any warnings about inferences

michihuber15:01:07

but it does crash and can be fixed by ^js'ing win and Settings (maybe either is sufficient, have only tested both)

thheller15:01:59

this should definitely give you externs warnings?

thheller15:01:11

did you set :infer-externs in your build config somewhere?

thheller15:01:36

or are you using some ultra ancient shadow-cljs version?

michihuber16:01:41

I did get a lot of warnings without setting any :infer-externs option – after silencing all warnings, this one remained (I saw that the default was what I wanted)

michihuber16:01:47

I just recompiled with explicit :infer-externs :auto and still no warnings

thheller16:01:38

what are win and sSettings in the above?

michihuber16:01:41

(I mean no extra warnings)

thheller16:01:13

what does "extra" mean?

michihuber16:01:30

when I ran the build the first time I did get a lot of warnings that I silenced

michihuber16:01:42

... source code ...

michihuber16:01:09

hm, it seems the win is tagged as js in the let, but that doesn't carry through to the closure?

thheller16:01:55

win isn't tagged at all

thheller16:01:14

should be ^js win (BrowserWindow. (clj->js opts))

thheller16:01:59

and you are tagging a bunch of stuff that doesn't need tags at all

michihuber16:01:48

yeah, I was tagging lots of stuff to debug this

michihuber16:01:07

but where do I trip up the warnings?

thheller16:01:22

which warnings?

michihuber16:01:38

shouldn't it give me a warning that I'm not tagging win?

thheller16:01:42

I'm still guessing mostly in the dark about what you are asking me

thheller16:01:48

so please be specific 😛

thheller16:01:13

no, you should get warnings about locations where it cannot infer externs

thheller16:01:52

tagging win once in the start should pretty much be enough for most things I see there

thheller16:01:19

its always best to tag the name symbol, not the form that creates it

thheller16:01:57

win ^js (BrowserWindow. (clj->js opts)) is not ideal since there are a few places in the compiler that lose type hints. I'm not sure this is one but to be sure just move it to the left

thheller16:01:33

> when I ran the build the first time I did get a lot of warnings that I silenced

thheller16:01:38

what do you mean by silencing?

michihuber16:01:48

I mean I tagged the locations it gave me

michihuber16:01:30

should I try reverting the tagging, go through the inference warnings again, but tag the symbols, not the expressions and see if that fixes it? or is that not the cause?

thheller16:01:10

I don't know the cause. I haven't seen the exact error. I'm guessing in the dark

michihuber17:01:32

ok, I'll try that

michihuber17:01:37

and report back

michihuber17:01:03

(at this point, just getting runtime errors related to non-externed symbols, fwiw)

michihuber17:01:22

but without getting non-inferrable externs warnings for those symbols

michihuber17:01:46

no compile errors etc.

michihuber14:01:40

update: I diligently fixed inference warnings the errors by tagging the named symbol where it appears first. this fixed the build 🎉 (I was led astray originally because of broken builds due to caching)

michihuber14:01:14

that said: I get a lot of runtime errors due to missing externs

michihuber14:01:39

there definitely is some kind of issue with inference of JS objects that get passed into a function through a clj map

michihuber14:01:01

e.g.

(defn do-stuff [system]
  (let [{:keys [Dialog]} system]
    (.doSomething Dialog "foo")))
we do this kind of stuff a lot. system is a booted integrant system, Dialog is (.-dialog Electron) no warning about Dialog at build time, but xy is not a function during runtime

thheller14:01:15

this should absolute 100% generate a warning

michihuber14:01:39

any way I can debug this?

thheller14:01:39

do you mistakenly set :infer-externs true in your build config?

thheller14:01:04

or somewhere else mess with *warn-on-infer*?

michihuber14:01:05

{:editor {:target :browser
           :output-dir "resources/public/js/compiled/"
           :modules {:editor {:entries [editor.core]}}
           :externs [
                     "resources/externs/react.ext.js"
                     "resources/externs/react-dom.ext.js"]}
  :analyzer {:target :browser
             :output-dir "resources/public/js/compiled/"
             :modules {:analyzer {:entries [analyzer.core]
                                  :web-worker true}}}
  :app {:target :node-script
        :main app.core/main
        :output-to "resources/public/app.js"}
  }

michihuber14:01:36

this is our :builds key – we only h ave source-paths and dependencies set otherwise

michihuber14:01:40

just grepped for warn-on-infer and nothing came up

thheller14:01:32

I just took your code and code no warning either

thheller14:01:11

let me check

thheller15:01:08

hmm this indeed seems to be a pattern that never produces any inference warnings

thheller15:01:20

so dot-interop on anything destructured in a let binding

michihuber15:01:52

anything I can do to help with that? or would you recommend tagging manually for now as a fix is not straightforward?

thheller15:01:12

you can upgrade to 2.20.17. that should give you warnings for this pattern

michihuber15:01:18

🙌🙌🙌

michihuber15:01:52

got lots of new warnings, thanks! fyi, injecting symbols like Path or Url using this pattern does still not trigger warnings, though. (but e.g. FS App Dialog do trigger warnings)

michihuber15:01:26

and it seems it sometimes only triggers one (local) occurrence, though not for later injections in different defn's further down the file

thheller16:01:27

not everything requires externs so that might be alright