What do i have to provide to squint to get it working with a function like that
(defn cljs-module [filename]
[:script {:type "module"}
(->
(str "cljs/" filename ".cljs")
io/resource
slurp
squint/compile-string
h/raw)])
The resulting code is the module javascript code i could generally use in a <script type="module"> tag. My question is i have following cljs code
(require '["" :as react])
(require '["" :as hooks])
(defn Counter []
(let [[counter setCounter] (hooks/useState 0)]
#jsx [:<>
[:div "Counter " counter]
[:button {:onClick #(setCounter (inc counter))} "+"]
[:button {:onClick #(setCounter (dec counter))} "-"]]))
(defonce el (js/document.getElementById "cljs"))
(react/render #jsx [Counter] el)
and want to be able to compile it on the server and render it in my page and the preact component should show up. What am i missing? Importmaps? cause the browser tells me the generated jsx can't be understand ๐JSX is not something that a browser understands, you need to transpile that further, unless you compile using the runtime format. Let me find this example...
thought so but would it be possible with squint compiler to get that compiled version
let me find out how to use this on the command line... there is a way
that would be awsesome
than i could extend the clj-mnl-web thing where you can even compile preact react stuff on the fly and embed it in the site ๐ฎ
ah wait, you use squint/compile-string
exactly
can you feed it some options like:
{:jsx-runtime {:import-source ""}} if this isn't documented anywhere, we should
ok i still have issues ๐ i compile a simple gist one moment D
here ya go
I have to look up how to clone a gist again...
got it
ok first thing: upgrade squint
:git/sha "c86d83bd3741a710e2f80fecd413801ddd456e64"then you'll encounter:
Uncaught TypeError: Failed to resolve module specifier "squint-cljs/core.js". Relative references must start with either "/", "./", or "../".which you can fix by updating the import maps
So this whole thing works now:
(ns index
(:require [babashka.deps :as deps]
[hiccup2.core :as h]
[org.httpkit.server :as srv]
[cheshire.core :as json]))
(deps/add-deps '{:deps {io.github.squint-cljs/squint {:git/url "" :git/sha "c86d83bd3741a710e2f80fecd413801ddd456e64"}}})
(require '[squint.compiler :as squint])
(defn compile-jsx [src]
(squint/compile-string src {:jsx-runtime {:import-source ""}}))
(defn cljs-module [filename]
[:script {:type "module"}
(->
filename
slurp
compile-jsx
h/raw)])
(defn page [_]
{:body (str (h/html
[:html
[:head
[:script {:type "importmap"}
(h/raw
(json/generate-string
{:imports
{"squint-cljs/core.js" ""
"squint-cljs/src/squint/core.js" ""}}))]
;;
;; thats the module i want to compile as plain js module where the jsx is allready transpiled
;;
(cljs-module "test.cljs")]
[:body
[:div#cljs]]]))
:status 200})
(srv/run-server #'page {:port 8888})
(println "Server started at ")
@(promise) oh my god
๐ฎ exactly what i wanted ๐
this is amazing THANK YOU SOOOOO MUCH
๐
just one more questions should i add the other deps in the import map too ?
regarding squint? or is there a bundled version
what other deps?
in the import map
"squint-cljs/core.js": "./src/squint/core.js", "squint-cljs/string.js": "./src/squint/string.js", "squint-cljs/src/squint/string.js": "./src/squint/string.js", "squint-cljs/src/squint/set.js": "./src/squint/set.js", "squint-cljs/src/squint/html.js": "./src/squint/html.js",
?
those
it depends if you use those, if so, yes
ok great thats really cool now
looking forward to your blog post on this sometime ;P
will do so sir still figuring stuff out thats why i pushed that clj-mnl thing out to see what i can do better ๐
:-D
One thing I ended up doing is the following
(def $ react/createElement)
($ :div {} "counter")
It works without any JSX transforms and the syntax is something I'm already used to from UIX@martinklepsch all of the above works without JSX transforms
exactly and its amazing
just take a look at https://github.com/m3tti/clj-mnl-web/blob/master/src/view/components.clj and https://github.com/m3tti/clj-mnl-web/blob/master/resources/cljs/helloworld.cljs which basically compiles the component on the server ๐
Ah, it does the JSX stuff at runtime? Hadn't seen that before ๐ Just also wanted to share an alternative approach
also great @martinklepsch but i wanted to have all stuff happen on the server now i can write cljs without the need of node ๐
@martinklepsch you can the see the output of this feature here: https://squint-cljs.github.io/squint/?repl=false&jsx.import-source=https%3A%2F%2Fesm.sh%2Fpreact%4010.19.2&src=KHJlcXVpcmUgJ1siaHR0cHM6Ly9lc20uc2gvcHJlYWN0QDEwLjE5LjIiIDphcyByZWFjdF0pCihyZXF1aXJlICdbImh0dHBzOi8vZXNtLnNoL3ByZWFjdEAxMC4xOS4yL2hvb2tzIiA6YXMgaG9va3NdKQoKKGRlZm9uY2UgY29tcG9uZW50LXN0YXRlIChhdG9tIDApKQoKKGRlZm4gQmFyIFt7OmtleXMgW2ZpcnN0bmFtZSBsYXN0bmFtZV0gOmFzIHByb3BzfV0KICAobGV0IFtbY2xpY2tzIHNldENsaWNrc10gKGhvb2tzL3VzZVN0YXRlIEBjb21wb25lbnQtc3RhdGUpXQogICAgI2pzeCBbOjw%2BCiAgICAgICAgICBbOnNwYW4gZmlyc3RuYW1lICIgIiBsYXN0bmFtZV0KICAgICAgICAgIFs6ZGl2ICJZb3UgY2xpY2tlZCAiIGNsaWNrcyAiIHRpbWVzISJdCiAgICAgICAgICBbOmJ1dHRvbiB7Om9uQ2xpY2sgIyhzZXRDbGlja3MgKHN3YXAhIGNvbXBvbmVudC1zdGF0ZSBpbmMpKX0KICAgICAgICAgICAiQ2xpY2sgbWUiXV0pKQoKKGRlZm4gRm9vIFtdCiAgI2pzeCBbOmRpdiAiSGVsbG8sICIKICAgICAgICAobGV0IFttIChhc3NvYyB7OmZpcnN0bmFtZSAiTWljaGllbCJ9IDpsYXN0bmFtZSAiQm9ya2VudCIpXQogICAgICAgICAgI2pzeCBbQmFyIHs6JiBtfV0pXSkKCihkZWZvbmNlIGVsdCAoZG90byAoanMvZG9jdW1lbnQuY3JlYXRlRWxlbWVudCAiZGl2IikKICAgICAgICAgICAgICAgKGpzL2RvY3VtZW50LmJvZHkucHJlcGVuZCkpKQoKKHJlYWN0L3JlbmRlciAjanN4IFtGb29dIGVsdCk%3D there's no special transform involved, squint supports outputting the jsx-runtime format
i'm also looking forward to move from compojure to ruuter so my idea also works for babashka
isn't that much of a change i guess ๐
all you need than is babashka thats amazing
@borkdude btw the multipart thing works with httpkit BUT we need to implement the entire multipart handling on our own ๐
thats the only part i see that would be missing except that nearly everything worked really really well
yeah that sucks
have you looked into multipart ๐ it looks like not much fun ๐
I've implemented multipart requests for bb.http-client ;)
so that's the other side
I guess you could use that, but do the reverse on the receiver side ;)
or the workaround: base64 encoding
btw @mathaeus.peter.sander I noticed that the squint version in the import maps is also a bit behind, might want to update that as well
will do
done
๐
someone commented on X that preact and webcomponents go well together https://preactjs.com/guide/v10/web-components/ never tried it, but perhaps a nice experiment with squint
Shouldn't be a big problem i guess
regarding web components with preact https://github.com/m3tti/borkweb/blob/master/resources/cljs/custom-element.cljs https://github.com/m3tti/borkweb/blob/24ed3ef7955ba522c526af0ee295a0d7b3a41b71/src/view/components.clj#L103 here you go added to borkweb ๐
nice!!!!
hi! loving squint ๐ what is the current situation wrt to being able to connect directly to the browser from the repl? this is the only thing that's stopping me from giving up "classic" cljs right now it's not so much about needing to dynamically redefine vars (hot reload with vite basically makes this redundant I guess?) but I miss being able to check the app state, test functions that call browser api's etc
That's the major missing piece right now, but something I plan to work on
you're right that hot-reloading can be taken care of using vite
I think it's technically possible, just have to connect the dots. I've done this for #scittle as well: https://github.com/babashka/scittle/tree/main/doc/nrepl
thanks a lot, looking forward to seeing what you come up with ๐ another question: you mention pitfalls around data structures being vanilla js, do you have any examples of this in practice? like, if I create a map and treat it just like I would in regular clj/cljs and don't let it touch any third-party library functions, can I assume it won't mutate?
that's a correct assumption, the squint stdlib doesn't mutate if the corresponding function in CLJS doesn't mutate either
one difference is structural equality, e.g. (= {:a 1} {:a 1}) would return false in squint
there's deepEquals stuff for this in JS land, but squint compiles = just to ===
also be aware that JS objects only have string keys, which is another difference
often stuff "just works" but when trying out an Advent of Code puzzle which uses assoc a million times on an object, you'll notice a difference in performance. There's good ways to optimize this, but it's different from CLJS where structural sharing makes it more efficient
it's also possible to use ImmutableJS in squint of course, for parts where this is important
ok yeah those are quite annoying but workable I guess ๐ not writing super perf-sensitive stuff so that should be fine thanks again!
there is a Node.js nREPL for squint, but nothing that connects to the browser. hopefully soon-ish!
yes I saw that re data structures: when I think about it maybe having to constantly write #js et al is equally annoying so it kind of cancels out
> squint does support compiling to a REPL format so you can then poke at global stuff.. How do I do that? I think I need some debugging in browser context
I quickly published a new squint version 0.8.115. There you can pass a --repl option to either squint compile or squint watch to compile into the REPL format
Sorry of documented elsewhere, but what does โRepl Formatโ mean? Where does the output go?
it's not really documented as of today, but you can view the difference in the squint playground by turning "REPL mode" on and off: https://squint-cljs.github.io/squint/
@sr Poor man's browser REPL solution: squint does support compiling to a REPL format so you can then poke at global stuff like this:
I'm looking into a proper solution right now, but takes a while
nice so this is available right now?
if I merge a branch with a small change and publish that, yes, then you can run npx squint watch --repl which watches the sources directories and compiles using repl output
I could do that now if that's useful to you
I'm looking into making the nREPL server work over a websocket connection to make eval work in the browser, but this is more gnarly
ok I think I'll wait for full nREPL support
ok