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")
see https://clojurescript.org/guides/webpack or use shadow-cljs
the guide you linked is outdated and not recommended today
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"}}
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.
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?
which part of ES6? 😛
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
@mike.j.cusack and you can do stuff like:
(apply + (range 1000))
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. 😄
I can relate to “just never been a fan of JavaScript” 😂
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
the compiler takes care of writing JS code that doesn't have those issues
How?
how what? any particular thing you are worried about?
How does the compiler use vars and not have issues?
the same way you did in "old" JS if you were careful
?
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?
There’s no how .. the generated code won’t have functions manipulating that var
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
a) namespacing b) shadowing
(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?
nothing
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
@mike.j.cusack 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
run it through prettier
JS or so
this can give you a good sense for how CLJS code gets converted to JS, before optimizations are run: http://app.klipse.tech/
you can type in CLJS code and see the JS output
I can't type into the cljs box
hmm strange. are you on mobile?
I also can't see the JS code?
Nope. And tried with Firefox and Chromium
🤷:skin-tone-2: it works on the latest Chrome on my mac for me
I'm sure there are other places out there
to view this sort of thing
the code compiles and runs fine but I can't see the JS anywhere
hmm. here's what I see
For me the cljs is generated from the clj
And it's not actually cljs code
hmm yeah that works but
(fn [a] (let [a (inc a)] (+ a a)))
doesn'tdisregard the CLJ/CLJS symbols. they are kinda confusing. this thing only supports CLJS.
@thheller that is weird :thinking_face: it shows JS code once I wrap it with (def foo ,,,)
yeah to be clear @mike.j.cusack: 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
hmm indeed. maybe I should build a thing like this for shadow-cljs 😉
that would be neat! 😄
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. 🙂