This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2021-03-03
Channels
- # announcements (2)
- # babashka (154)
- # beginners (63)
- # calva (4)
- # cider (2)
- # clara (19)
- # clj-kondo (94)
- # cljfx (8)
- # cljs-dev (6)
- # clojars (2)
- # clojure (82)
- # clojure-australia (1)
- # clojure-europe (134)
- # clojure-italy (4)
- # clojure-nl (5)
- # clojure-serbia (11)
- # clojure-taiwan (1)
- # clojure-uk (39)
- # clojurescript (83)
- # community-development (108)
- # conjure (10)
- # cursive (32)
- # data-oriented-programming (1)
- # datomic (22)
- # defnpodcast (9)
- # depstar (4)
- # docker (3)
- # events (3)
- # figwheel-main (2)
- # funcool (9)
- # graalvm (19)
- # honeysql (23)
- # jackdaw (4)
- # jobs (4)
- # jobs-discuss (2)
- # kaocha (24)
- # leiningen (1)
- # lsp (12)
- # membrane (6)
- # off-topic (21)
- # pathom (13)
- # polylith (1)
- # releases (7)
- # remote-jobs (2)
- # reveal (8)
- # ring (7)
- # sci (2)
- # shadow-cljs (9)
- # sql (10)
- # tools-deps (21)
Does anyone know, when https://clojurescript.org/news/2017-07-12-clojurescript-is-not-an-island-integrating-node-modules, how do we reference packages with @
symbols. In this case @google-cloud/pubsub
?
A) Ie how would we include it in a build.edn
like this. The example here fails to fetch the module.
{:target :nodejs
:output-dir "public/js/compiled"
:output-to "public/js/main.js"
:install-deps true
:npm-deps {:express "4.17.1"
:@google-cloud/pubsub "2.1.0"}}
B) And with the right incantation, how would we load it in?
(require '"@google-cloud/pubsub")
(require '"google-cloud/pubsub")
(require '"@pubsub")
(require '"pubsub")
Ok, so I know the “require” is this: (require '["@google-cloud/pubsub" :as pubsub])
.
But still wondering howto get the Clojurescript compiler to pull it in.
see https://clojurescript.org/guides/webpack or use shadow-cljs
Ok, I glanced again at Clojuerscript’s https://clojurescript.org/reference/compiler-options#npm-deps. And it just looks like we need to wrap the @package/name
in a string. So that was my initial failure to notice.
This works for me.
{:target :nodejs
:install-deps true
:npm-deps {:express "4.17.1"
"@google-cloud/pubsub" "2.1.0"}}
client: we want a web based solution. also the server has to run behind our firewall. also everything is windows. me: 😎
$ make phoenix-classify-server.exe
npx shadow-cljs release server app --debug
shadow-cljs - config: /home/chrism/dev/phoenix-species-photo-classifier/shadow-cljs.edn
shadow-cljs - connected to server
[:server] Compiling ...
[:server] Build completed. (81 files, 1 compiled, 0 warnings, 4.21s)
[:app] Compiling ...
[:app] Build completed. (79 files, 0 compiled, 0 warnings, 4.86s)
cp -v public/*.css build/public/
'public/mui.min.css' -> 'build/public/mui.min.css'
'public/style.css' -> 'build/public/style.css'
cp -v public/index.html build/public/
'public/index.html' -> 'build/public/index.html'
npx nexe build/server.js -r "./build/server.js.map" -r "./build/public/**/*" -t win32-x86-12.16.2 -o phoenix-classify-server.exe
ℹ nexe 4.0.0-beta.17
✔ Included 7 file(s)
✔ Already downloaded...
✔ Compiling result
✔ Entry: 'build/server.js' written to: phoenix-classify-server.exe
✔ Finished in 1.175s
anyone else using nexe
to ship cljs?How do you use Reveal with ClojureScript in Cursive?
For people using Reagent and want to style with Material Design how are you going about it?
Is there any way to generate ES6+ JS with CLJS?
The useful bits like let and const
how would that be useful for us? but the answer to that is no, there is no way to make the compiler generate those.
How is generating old JS with only vars ok in CLJS, but yet if you did that in vanllla JS people would blow your head off?
I must be missing something
How does the compiler use vars and not have issues?
what particular thing are you worried about? I really cannot explain the entire compiler over slack 😛
I'm trying to understand how it can use vars (mutable) and not have issues around the mutability
But I don't know the compiler under the hood
Just a broad idea ... when you write cljs code and use a variable within a function, the compiler makes sure that generated var won’t be touched by anything else outside of that scope .. so practically it’s treated like a let.
Ok, and how?
I'm saying how does it ensure that
If you wanted to take the compiled code and change that var I guess you could .. but the code is produced to not ever touch that var
(def a 1)
becomes some.ns.a = 1
so it can't clash with (def a 1)
in some other ns since that will have a different name
then if you shadow yourself like (fn [a] (let [a (inc a)] ...)
second a
will actuall have a different name and not mess with the other one
And what is stopping some.ns.a from being changed to 2?
So how is that ok?
it is just how CLJ(S) works and just because you can do certain things does not mean that you should. so people in general won't
So what's stopping rogue code from doing it?
just like const
is pretty much useless in JS. const a = { foo: 1 }
can still do a.foo = 2;
That's true and one of my peeves of JS
But let still does what it claims
@U01NYKKE69G the semantics of Clojure, which the compiler implements, doesn't allow mutation of vars. So if all your code is in ClojureScript, then the semantics will remain
Ok. I'm just trying to learn the actual how. I like having a thorough understanding of things.
I'm trusting that what you guys are saying is true. I just want to know the details to better understand the code
the common problems you can have in JS are not issues you'll have in CLJS. the compiler takes care of the quirks and ensures that the code actually does what you told it to do
when the compiler takes your ClojureScript code and converts it to JS, the compiler has rules for how it should write code. It outputs JS code in such a way that it won't cause some of the maintenance issues, like hoisting or mutating things willy-nilly
Ok...how
that's kind of a hard question to answer. It is "a simple matter of programming" as it were
study the generated code or compiler I guess. that'll give you more answers than we can.
the compiler has a bunch of different steps that parses your code, analyzes your code, and then turns it into JS according to a set of common rules. those are all implemented in code
Studying the generated code is really difficult because of how it is all smashed together
this can give you a good sense for how CLJS code gets converted to JS, before optimizations are run: http://app.klipse.tech/
I can't type into the cljs box
Nope. And tried with Firefox and Chromium
For me the cljs is generated from the clj
And it's not actually cljs code
disregard the CLJ/CLJS symbols. they are kinda confusing. this thing only supports CLJS.
@U05224H0W that is weird :thinking_face: it shows JS code once I wrap it with (def foo ,,,)
yeah to be clear @U01NYKKE69G: the code on the left is the ClojureScript code that one would write, and on the right is the JavaScript code that the compiler outputs
Ok, now this is helpful, thanks.
Try:
(defn example []
(let [[count set-count] (js/React.useState 0)]
[:div#example
[:p "You clicked " count " amount of times"]
[:> js/MaterialUI.Button
{:on-click #(set-count inc)
:color "primary"
:variant "contained"}
"Click"]]))
So it immediately invokes the functions
That makes sense
if you want to get extra confused look at some :advanced
optimized output. that is completely mind boggling what the compiler does with that sometimes. 🙂
@U01NYKKE69G also to see fn bodies at the REPL, try
(set! *print-fn-bodies* true)
=> (set! print-fn-bodies true) => + #object[cljs$core$PLUS “function cljs$core$PLUS(var_args){ var G__10823 = arguments.length; switch (G__10823) { case 0: return cljs.core.PLUS.cljs$core$IFn$_invoke$arity$0(); break; case 1: return cljs.core.PLUS.cljs$core$IFn$_invoke$arity$1((arguments[(0)])); break; case 2: return cljs.core.PLUS.cljs$core$IFn$_invoke$arity$2((arguments[(0)]),(arguments[(1)])); break; default: var args_arr__9263__auto__ = []; var len__9238__auto___10825 = arguments.length; var i__9239__auto___10826 = (0); while(true){ if((i__9239__auto___10826 < len__9238__auto___10825)){ args_arr__9263__auto__.push((arguments[i__9239__auto___10826])); var G__10827 = (i__9239__auto___10826 + (1)); i__9239__auto___10826 = G__10827; continue; } else { } break; } var argseq__9264__auto__ = (new cljs.core.IndexedSeq(args_arr__9263__auto__.slice((2)),(0),null)); return cljs.core.PLUS.cljs$core$IFn$invoke$arity$variadic((arguments[(0)]),(arguments[(1)]),argseq_9264__auto__); } }“]
Thanks for the tip! Man, that's a lot for just +
+
is just +
in most cases in the code. the above is just variadic function dispatch boilerplate since you can't actually use +
that way in JS
Ah, ok
@U01NYKKE69G and you can do stuff like:
Haha, I'm not new to Clojure and ClojureScript. I've just never been a fan of JavaScript so the fact ClojureScript removes that burden has caused me to exist peacefully without opening the hood. I have looked a bit under the hood for Clojure though. I'm not sure why I have a sudden interest in opening the hood now. 😄