Fork me on GitHub
#shadow-cljs
<
2022-04-16
>
pinkfrog03:04:07

I am following the tutorial here: https://clojurescript.org/guides/promise-interop#using-promises-with-core-async. Failed with

TypeError: undefined is not an object (evaluating 'cljs.core.async.interop._LT_p_BANG_')
Example code:
(ns simple.example
  (:require
   [cljs.core.async :refer [go]]
   [cljs.core.async.interop :refer [<p!]]))

(go
  (println (<p! (js/Promise.resolve 42))))

thheller05:04:00

@i can't say anything without more context. what build :target is this? any compilation errors? any console warnings/errors besides that one?

pinkfrog05:04:47

deps.edn: https://bpa.st/FNZA shadowcljs.edn: https://bpa.st/NNSA the target is react-native

thheller05:04:42

looks fine as far as I can tell so far

thheller05:04:40

the error is saying that it tried to call <p! as a function. but it is a macro, so that does not work. dunno why. need more info and reproducible example would help

pinkfrog05:04:30

I am going to make one.

pinkfrog06:04:14

bulk of the code is from the react-native template

thheller06:04:54

> in the repl, load the app.example namespace

thheller06:04:30

the react-native is rather limited in what it can do

thheller06:04:42

just require the namespace properly in your build?

pinkfrog06:04:00

> just require the namespace properly in your build? What do you mean?

thheller06:04:19

app.example is not required anywhere, so it is not part of the build

thheller06:04:44

require it in app.main and it will be compiled properly

pinkfrog06:04:07

Good point! Let me try.

pinkfrog06:04:00

That works!

pinkfrog06:04:15

Trapped by this several times (in similar issues).

pinkfrog06:04:29

Packages are bundled as they are needed.

pinkfrog06:04:54

@U2FRKM4TW FYI, the issue was the interop package not bundled.

👍 1
thheller06:04:26

thats because all code compiled needs to go shadow-cljs -> metro -> runtime. in case of the REPL it directly goes shadow-cljs -> runtime since there is no way to tell metro to compile a small piece of code

thheller06:04:05

so it fails quite often. although technically this should work in this case given that no new npm dependencies are involved

thheller06:04:33

but still the code transformations metro does will be missing so there is no way to tell how these variants of code interact

thheller06:04:30

if someone wants to dig into this feel free to ask questions. I already fail at getting react-native running on windows and I don't have any interest to waste any more time on this

thheller05:04:33

do you use deps.edn or project.clj? which core.async version?

Chris McCormick06:04:49

In nbb I have to require es6 modules like this: ["passport$default" :as passport] and in shadow-cljs i have to require them like this: ["passport" :as passport] - I am employing https://github.com/chr15m/sitefox/blob/main/src/sitefox/deps.cljc to make my library work under both nbb and shadow-cljs. Is there no way that I can reconcile these with a single require syntax? Is there any chance shadow-cljs would support "passport$default" in the future?

thheller06:04:24

this is strictly speaking not related to shadow-cljs, it is related to what kind of output you use. if you use :target :esm the $default will just work (as that is also what nbb is using)

thheller06:04:06

if you however use :node-script or :node-library or :npm-module those all output commonjs, where require is just different

thheller06:04:44

oh and you need to run node in module mode too of course when using :esm

Chris McCormick06:04:55

ah ok. i remember now you told me this already. i don't really want to force :target :esm on consumers of the library so i'm at a bit of a loss what to do.

thheller06:04:12

thats not something shadow-cljs can do anything about. it is unfortunately not a clean transition but that is node for ya 😉

👍 1
Chris McCormick06:04:14

coming from php and (even worse) python, node is suprisingly smooth 😁 - python is the absolute worst for jarring incompatible language changes.

Chris McCormick06:04:38

can i just clarify from what you wrote above that :target :node-script can't use the $default syntax and :target :esm has to be used instead if i want that?

Chris McCormick06:04:08

i'm just thinking if i should just switch to :esm and change my npm create projects to run the server in esm mode instead. :thinking_face:

thheller06:04:28

$default is not related to esm or build target in any way. it is syntax sugar, nothing else. think of foo$default translating to require("foo").default or in the case of ESM and using import it translates directly to import default from "foo"

thheller06:04:02

ESM has this special case for default imports that commonjs didn't have. that is the crux of the problem. something new introduced and used by ESM packages

Chris McCormick06:04:04

understood. so theoretically would it be possible for the cljs compiler to ignore $default - i.e. replace it with whitespace, when used in commonjs mode? or is that just a terrible idea?

thheller06:04:04

sounds like a bad idea to me