This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-04-16
Channels
- # announcements (2)
- # asami (5)
- # babashka (52)
- # beginners (42)
- # biff (3)
- # cljdoc (4)
- # cljsrn (2)
- # clojure (30)
- # clojure-austin (35)
- # clojure-dev (3)
- # clojure-france (11)
- # clojurescript (36)
- # conjure (6)
- # cursive (5)
- # fulcro (33)
- # graalvm (41)
- # lsp (54)
- # malli (1)
- # music (2)
- # off-topic (7)
- # overtone (1)
- # pedestal (5)
- # polylith (2)
- # remote-jobs (1)
- # sci (28)
- # shadow-cljs (38)
- # vim (15)
- # web-security (1)
- # xtdb (8)
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))))
@i can't say anything without more context. what build :target
is this? any compilation errors? any console warnings/errors besides that one?
deps.edn: https://bpa.st/FNZA shadowcljs.edn: https://bpa.st/NNSA the target is react-native
cljs -Stree output: https://bpa.st/GOWQ
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
Here is the mininal example:https://github.com/introom/rn-example/blob/main/readme.md
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
so it fails quite often. although technically this should work in this case given that no new npm dependencies are involved
but still the code transformations metro
does will be missing so there is no way to tell how these variants of code interact
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
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?
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)
if you however use :node-script
or :node-library
or :npm-module
those all output commonjs, where require is just different
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.
thats not something shadow-cljs can do anything about. it is unfortunately not a clean transition but that is node for ya 😉
coming from php and (even worse) python, node is suprisingly smooth 😁 - python is the absolute worst for jarring incompatible language changes.
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?
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:
$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"
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
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?