This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-06-27
Channels
- # aleph (10)
- # beginners (139)
- # cider (47)
- # clara (19)
- # cljs-dev (2)
- # cljsjs (9)
- # clojure (94)
- # clojure-berlin (1)
- # clojure-dev (23)
- # clojure-greece (5)
- # clojure-italy (5)
- # clojure-nl (14)
- # clojure-uk (36)
- # clojurescript (85)
- # cursive (2)
- # datomic (56)
- # emacs (3)
- # events (1)
- # fulcro (33)
- # garden (3)
- # graphql (6)
- # hoplon (53)
- # jobs (1)
- # leiningen (4)
- # mount (46)
- # nrepl (7)
- # off-topic (8)
- # om (3)
- # other-languages (4)
- # pedestal (7)
- # portkey (7)
- # re-frame (1)
- # reagent (16)
- # remote-jobs (3)
- # ring-swagger (2)
- # shadow-cljs (16)
- # slack-help (2)
- # tools-deps (2)
- # yada (1)
Is it possible to use javascript async
and await
in Clojurescript?
@viebel short answer is no. long answer is https://clojureverse.org/t/async-generator-functions-in-cljs-requesting-feedback/2262 pragmatic answer is check out the promesa
library which has some solutions (see their alet
and async
macros)
thanks @lee.justin.m. My use case is that I want to expose a clojurescript function that returns core.async channel for javascript consumption
Any tips on that?
I do not know if there is any reasonable way to directly consume a channel from javascript. I think you’d want to expose a more idiomatic interface, like an event-based model for streams or a promise model for a single value
For the moment, I am handling it with javascript promises like that:
(defn foo-js-promise [args]
(js/Promise. (fn [resolve reject]
(go (let [[status data] (<! (foo args))]
(if (= :ok status)
(resolve data)
(reject data)))))))
yea if there’s just one value, then that’s a pretty good interface. any reason why you don’t like it?
let me trry it
How do I trigger advanced optimization on js files included in my cljs project?
One of my projects starts up slowly, and I finally took a look at it today. It is loading a 1.5MB app.js, of which about half is a complete copy of semantic-ui-react.inc.js indirectly loaded frm cljsjs from one of my project dependencies.
I'm compiling with :optimizations :advanced
, so I'm surprised that it was not optimized. Is this expected behavior? Or did I just configure something wrong?
@deg forein libs (ie. cljsjs) are never passed through :advanced
so yes that is totally expected.
Ah, ok. Too bad. Is there any way to force it to be optimized, or any other recommended tricks/techniques?
@deg i haven’t looked at semantic-ui specifically but most of these ui libraries are huge because they provide 100 different components and you only use 10 of them. all the ones I’ve looked at solve this by making it possible to include each component separately.
do i remember right that cljs supported "compiler macros" at one point? the ability to define macros to use in place of inline function calls. does it still?
I found the announcement about adding npm-deps (https://clojurescript.org/guides/javascript-modules) but compiling with a react-router-dom
dependency leads to java.lang.NullPointerException
@anton for just getting things to work, you’ll want to try https://clojurescript.org/guides/webpack or https://shadow-cljs.github.io/docs/UsersGuide.html
the :npm-deps
feature is a bit advanced and doesn’t have all the kinks worked out yet
which is the more common between those two options? It seems like the first one could be integrated with Boot
oops sorry @anton i misread. you are actually using the :foreign-libs
interface, which should work
I really like the hot reloading capabilities that a setup with Boot provides, so I'm trying to figure out if it's possible to use Boot in conjunction with either of those two options
yes it definitely is. if you use the standard cljs compiler (as opposed to shadow-cljs), you can include npm modules using the :foreign-libs
interface. the “webpack” solution just makes this a bit simpler by ensuring that all of the dependencies get processed into single browser compatible bundle. this means you just need a single import. boot is really neither here nor there on this: you need to set up webpack outside of boot, produce your bundle, and then pass the right options to the compiler.
the tricky part here is that some cljs packages (like reagent) already include the javascript they need (like react)
you can exclude the cljsjs package like this [reagent "0.7.0" :exclusions [cljsjs/react]]
(or whatever it is that you need to exclude) and then add it to the webpack bundle (or whatever solution you are using)
@alandipert Well, in ClojureScript you can have a macro with the same name as a function and then get the best of both worlds.
More details: http://blog.fikesfarm.com/posts/2015-12-12-clojurescript-macro-functions.html
@mfikes thanks, that's exactly what i was looking for
I've got one more question - I posted about this on the forum, but maybe you could give some more in-depth help
often react projects have really nested folder hierarchies and having to write out 10 levels of folders seems really awkward
so i’m not an expert, but I think the answer to your question is no. and i’m pretty sure it’s due to the underlying java infrastructure (but I don’t really know). maybe there is some solution. let’s see if anyone answers. (maybe symlinks?)
especially after being able to use index.js
to just import a bunch of modules from a folder
e.g. if you have foo.bar.baz
,
, foo.bar.abc
, etc. you can have a top-level foo.bar
that re-exports the public vars in those lower namespaces
if you have foo/bar/baz.cljs, foo/bar/xyz.cljs, foo/bar/abc.cljs, you can also have a foo/bar.cljs
the only bummer is that ClojureScript doesn't have use
so you'll have to manually write out all of the vars you want to expose in foo/bar.cljs
but what I'm talking about is inside of foo/bar.cljs
you'll need to write something like:
(ns foo.bar
(:require [foo.bar.baz :as baz]
[ :as xyz]
[foo.bar.abc :as abc]))
;; export vars from baz
(defn do-thing [x]
(baz/do-thing x))
(defn something-else [x y]
(baz/something-else x y))
;; ...
honestly I'm starting to realize that this problem isn't big enough to warrant an elaborate solution like that
Could you maybe have a registry of components (which in Reagent are more or less just data) and then a lookup function for that registry?
Your registry would be a data structure with some kind of hierarchy that replaces the namespace hierarchy
and then you could define a defcomponent
macro that automatically places functions in that registry...
I guess it’s a question of temper. There are probably performance advantages to using components, but there’s a certain simplicity to using functions.
Yes, it would probably make it easier to use. A macro can help defining an API. But often I’m a bit reluctant on settling on a certain API, so I guess I tend to start out with functions that manipulate data, which may be more tedious to use, but also very explicit.
That definitely makes sense - you start out with functions and once you have a working copy migrate to macros.
(I'm guessing you're using Reagent and it's in something like [:> SomeComponent ...]
)
it is a shorthand for adapt-react-class
https://github.com/reagent-project/reagent/blob/master/doc/InteropWithReact.md#creating-reagent-components-from-react-components
@lee.justin.m your solution to use Shadow-CLJS also worked perfectly
I think I have a fundamental misunderstanding of secretary routing. With no prefix set, and the following routes:
(secretary/defroute "/b" [query-params]
(reset! current-render-fn (fn [] [:h1 "B"])))
(secretary/defroute "/b/x" [query-params]
(reset! current-render-fn (fn [] [:h1 "B/X"])))
(secretary/defroute "/b/*" [query-params]
(reset! current-render-fn (fn [] [:h1 "B CATCH ALL"])))
(secretary/defroute "*" [query-params]
(reset! current-render-fn (fn [] [:h1 "CATCH ALL"])))
Why do I see "B/X" when I visit http://localhost:3000/a/#b/x ?
Similarly, why do I see "CATCH ALL" when I visit http://localhost:3000/b/x ?