This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2020-03-06
Channels
- # announcements (1)
- # aws (36)
- # babashka (105)
- # beginners (53)
- # calva (27)
- # cider (5)
- # clj-kondo (10)
- # clojure (232)
- # clojure-europe (4)
- # clojure-italy (6)
- # clojure-losangeles (9)
- # clojure-nl (3)
- # clojure-sanfrancisco (3)
- # clojure-uk (124)
- # clojured (3)
- # clojurescript (57)
- # clojutre (1)
- # core-async (9)
- # core-logic (1)
- # cryogen (23)
- # cursive (35)
- # datomic (12)
- # duct (4)
- # events (1)
- # figwheel-main (3)
- # fulcro (9)
- # graalvm (31)
- # jobs (1)
- # jobs-discuss (85)
- # kaocha (11)
- # leiningen (11)
- # luminus (19)
- # malli (47)
- # meander (12)
- # nrepl (8)
- # off-topic (32)
- # pathom (4)
- # pedestal (2)
- # reagent (7)
- # ring-swagger (1)
- # schema (3)
- # sql (5)
- # tools-deps (114)
- # vim (17)
- # xtdb (12)
Hi. I'm trying to create a simple react dashboard component and use it in a react app. I've managed to get everything running using re-frame. I'm using shadow-cljs and releasing it as a node-library. I've created a simple react app using create-react-app and there goes my nightmares. I can't find any good example where this has been done. Most of the articles do the reverse (using node modules in clojurescript). I'm also using material-ui via npm (was just experimenting). What is the right way of exporting and then importing this library. Any reference to a good example can also do.
Have you read this? https://shadow-cljs.github.io/docs/UsersGuide.html#target-node-library
Yes and when I try to use the generated js file in my react app it gives compile errors right from the first line e.g. "define is not defined"
note that you must publish a release build (ie. shadow-cljs release lib
). you cannot publish the results of watch/compile.
Anyone know how to use apply
for all constructors?
Ok:
(apply js/Error ["msg here"] )
Not ok:
(apply js/EventSource ["/path-here"] )
;=>
Uncaught TypeError: Failed to construct 'EventSource': Please use the 'new' operator, this DOM object constructor cannot be called as a function.
;; Ok
(let [sse (js/Function.prototype.bind.apply js/EventSource)]
(println "works" (new sse "/path-here")))
;; Not ok
(let [sse (js/Function.prototype.bind.apply js/EventSource)]
(println "__" (apply new sse ["/path-here"])))
create dedicated function (e.g. (defn error [& messages] (js/Error. (apply str messages)))
) and then call apply for that function: (apply error ["str1" "str2"])
ai 😞 Ok so no one size fits all solution. That’s a pity
It’s for the interpreter of https://github.com/borkdude/sci so I don’t know in advance what object will called
ah but I can fake apply with multiple arities
has there been any plan/debate/consideration for implementing a clojurescript parser+compiler independent of googles closure compiler? My experience with cljs so far is that the tooling is far less mature then I've become accustomed to in js development over the past few years. While I like the clj(s) language, I'd feel much more comfortable with using js tooling, making use of tried-and-tested treeshaking/minification/... as offered by webpack, rollup and the like; getting easy access to the full js ecosystem rather than having to work around the (imho) clunky behemoth that is the closure compiler and library. My instinct is that a cljs compiler that worked as eg a webpack loader or babel plugin and emitted (as much as possible) dependency-free es6 code could integrate far better in the js ecosystem. Did anyone consider this in the past and was it deemed a bad idea? Probably I'm overlooking aspects of the cljs->js conversion that are prohibitive of doing this?
Using shadow-cljs I didn't find myself missing anything from webpack/babel/etc. It can include modules from NPM, it'll minify node_modules even for node-library or node-script targets, and simplifies reload-on-save for any target...
The problem of adding a CLJS compiler as a babel source is that you the REPL, hot-reload, and most tooling will stop to work, for example
I'd argue that the closure-compiler is much more tried-and-tested in that area and has been for years 😛
Any feedback on the following approach to use apply
on constructors:
(defn constructor-fn [class]
(let [constructor (js/Function.prototype.bind.apply class)]
(fn
([a] (new constructor a))
([a b] (new constructor a b c))
([a b c] (new constructor a b c d))
([a b c d] (new constructor a b c d e))
([a b c d e] (new constructor a b c d e))
([a b c d e f] (new constructor a b c d e f))
([a b c d e f g] (new constructor a b c d e f g))
([a b c d e f g & more]
(throw (ex-info "Constructors with more than 7 arguments are not supported" {:class class}))))))
(apply (constructor-fn js/EventSource) ["/yeah"])
(thanks @delaguardo for the idea of having a dedicated function 🙂haha good question
I’m trying to (js/EventSource "/foo")
from the sci interpreter…. https://github.com/jeroenvandijk/sci/blob/51ad3e653e8759717bf7806b6cf51bf658d8a134/src/sci/impl/interop.cljc#L67
If you have ideas please let me know 🙂
normal constructors work, but (js/EventSource. "asdfsa")
doesn’t work with apply
I just checked and this solution doesn’t work in advanced compilation (not sure why)
WARNING: Use of undeclared Var sci.impl.interop/c at line 47 /Users/jeroen/Projects/Github/sci/src/sci/impl/interop.cljc
WARNING: Use of undeclared Var sci.impl.interop/d at line 48 /Users/jeroen/Projects/Github/sci/src/sci/impl/interop.cljc
WARNING: Use of undeclared Var sci.impl.interop/e at line 49 /Users/jeroen/Projects/Github/sci/src/sci/impl/interop.cljc
In the JVM it’s all reflection, but js doesn’t have that right?
hmm you mean I could call new
myself. True probably, but I would like to get the cljs
experience in sci
. So no context switching
pretend it’s the same
I already have this boilerplate in sci to avoid going through apply: https://github.com/borkdude/sci/blob/d768910b6c4f51fc9b3331f5d8ddefc59c1f4f36/src/sci/impl/interpreter.cljc#L395
I can remove the boilerplate, but it doesn’t seem to work in advanced mode yet. compiler doesn’t like c
, d
, and e
for some reason
and trying with one arity gives a weird error still. Ok back to the drawing board
Ah wait you mean not using apply at all. I can try that 🙂
(let [ctor (get-static-field [class field])]
(case (count args)
0 (new ctor)
1 (new ctor (nth args 0))
...))
awesome!
I think it does… but I am not entirely sure what I’m doing either
@thheller your suggestion works, sci.evalString("(js/EventSource. \"/aaa\")", {"classes": {"allow": "all", "js": window}})
works now
When I want to use addEventListener there is a new problem waiting 🙂
@thheller In case you are curious here is the WIP https://github.com/borkdude/sci/pull/286 still not perfect, but getting there
Thanks for your help!
Does anyone know if the metadata reader macro is supposed to work within go blocks? If I run (go (println (meta ^:foo {})))
it prints nil
to the console (whereas (go (println (meta (with-meta {} {:foo true}))))
and (println (meta ^:foo {}))
both print {:foo true}
)
I'm writing a library function that takes a data structure with optional metadata, so I'm thinking of turning the function into a macro that does (my-fn {:foo ^:bar {}})
-> (my-fn ((fn [] {:foo ^:bar {}})))
. It'll break any <!
s inside the call, but I'd rather do that than lose metadata silently. This should be ok, but I'm wondering if there's a better way.
(since wrapping the arg in a function prevents the go
block from clobbering the metadata).
hm... maybe the macro could instead do a clojure.walk/postwalk
and wrap anything that has metadata with with-meta
calls
looks to be a bug: https://clojure.atlassian.net/browse/ASYNC-192
ah, thanks for the link
cljs.user=> (require '[cljs.core.async :as a])
nil
cljs.user=> (macroexpand '(a/go (prn ^:foo {})))
(let* [c__45917__auto__ (cljs.core.async/chan 1)] (cljs.core.async.impl.dispatch/run (clojure.core/fn [] (clojure.core/let [f__45918__auto__ (clojure.core/let [switch__45894__auto__ (clojure.core/fn [state_127784] (clojure.core/let [state_val_127785 (clojure.core/aget state_127784 1)] (clojure.core/cond (clojure.core/== state_val_127785 1) (clojure.core/let [inst_127781 (. cljs.core/PersistentHashMap -EMPTY) inst_127782 (prn inst_127781) state_127784 state_127784] (cljs.core.async.impl.ioc-helpers/return-chan state_127784 inst_127782)))))] (clojure.core/fn state-machine__45895__auto__ ([] (cljs.core.async.impl.ioc-macros/aset-all! (clojure.core/make-array 7) 0 state-machine__45895__auto__ 1 1)) ([state_127784] (clojure.core/let [ret-value__45896__auto__ (try (clojure.core/loop [] (clojure.core/let [result__45897__auto__ (switch__45894__auto__ state_127784)] (if (cljs.core/keyword-identical? result__45897__auto__ :recur) (recur) result__45897__auto__))) (catch js/Object ex__45898__auto__ (cljs.core.async.impl.ioc-macros/aset-all! state_127784 5 ex__45898__auto__) (cljs.core.async.impl.ioc-helpers/process-exception state_127784) :recur))] (if (cljs.core/keyword-identical? ret-value__45896__auto__ :recur) (recur state_127784) ret-value__45896__auto__))))) state__45919__auto__ (clojure.core/-> (f__45918__auto__) (cljs.core.async.impl.ioc-macros/aset-all! cljs.core.async.impl.ioc-helpers/USER-START-IDX c__45917__auto__))] (cljs.core.async.impl.ioc-helpers/run-state-machine-wrapped state__45919__auto__)))) c__45917__auto__)
notably, this form:
(clojure.core/let [inst_127781 (. cljs.core/PersistentHashMap -EMPTY)
seems to be a rewritten version of the {}
that perhaps doesn’t propagate the metadata. I’m not sure why that happensIs it only empty colls? There is actually a ticket about this in Clojure
(go (println (meta ^:foo {:bar "baz"})))
also gives me nil
ok, just wanted to make sure this wasn't that. more likely both. :)