This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2019-11-11
Channels
- # adventofcode (1)
- # aleph (1)
- # announcements (3)
- # babashka (39)
- # beginners (84)
- # calva (1)
- # cider (17)
- # clj-kondo (15)
- # cljs-dev (43)
- # clojure (132)
- # clojure-dev (1)
- # clojure-europe (4)
- # clojure-nl (7)
- # clojure-norway (4)
- # clojure-uk (22)
- # clojurescript (56)
- # clojurex (24)
- # cursive (11)
- # data-science (2)
- # datascript (33)
- # datomic (7)
- # docker (2)
- # figwheel-main (11)
- # fulcro (2)
- # jobs (3)
- # joker (29)
- # leiningen (3)
- # nrepl (4)
- # off-topic (11)
- # planck (4)
- # reitit (5)
- # ring (4)
- # shadow-cljs (205)
- # spacemacs (5)
- # xtdb (9)
I keep getting this error when I try to watch / compile my dead simple app: Illegal UTF8 string in constant pool in class file jdk/nashorn/internal/runtime/linker/Bootstrap
I'm on
openjdk version "13" 2019-09-17
OpenJDK Runtime Environment AdoptOpenJDK (build 13+33)
OpenJDK 64-Bit Server VM AdoptOpenJDK (build 13+33, mixed mode, sharing)
the error is in a internal JDK class, nothing to do with shadow-cljs as far as I can tell
everything from jdk8 upwards should work fine. I usually upgrade when a new release is out and never had issues with v13, but I haven't tried the latest
I don't know. there is a jdk-13.0.1+9
release. maybe that fixes it? or just try the regular 13, not 13.0.1?
I actually got here to question about the workflow with emacs and CIDER, would you usually jack-in? or connect to a watch? how would you get auto-complete in the editor ?
I've never seen this error before and a quick google suggests it isn't very common either
I'll try or I'll just wait for a new release, I don't really care what JAVA version I'm running as long as it compiles to JS 😛
How would I connect from the nRepl to the browser? I mean, trying to run this code: (js/console.log "dsad")
is not working from nRepl beacuse it says there's no js namespace
Have you picked a CLJS REPL env after connecting to the Clojure REPL?
shadow.user> (shadow/repl :test-dev)
To quit, type: :cljs/quit
[:selected :test-dev]
cljs.user>
@eliraz.kedmi please specfiy what you mean by "rebuild"
okay. say I have the app running in dev mode with repl on. and now I'm adding the Material-UI library..
I can't just require the button from that library now, I need to quit the repl and rebuild it
so you do (require '["@material/core" :as x])
or whatever the package for that is nowadays
I'm guessing that you could run a command from the repl that stops the watch and restarts it
`(:require ["@reach/router" :refer [Router]] ["@material-ui/core" :refer [Button]] [hx.hooks :as hooks] [hx.react :as hx :refer [defnc]]))(:require ["@reach/router" :refer [Router]] ["@material-ui/core" :refer [Button]] [hx.hooks :as hooks] [hx.react :as hx :refer [defnc]]))`
I'm transferring an existing project to clojurescript, I currently do that in a very idiomatic way, how would you recommend to take advantage of the clojurescript power? any good courses you know about?
I'm backing off of attempting to add an option for shadow-cljs to reload the whole dependency tree of a changed ns. You're right it's the wrong way to approach this. We shouldn't hamstring our tools to make React happy. Also it doesn't fix REPL-driven development 😖
Instead I'm going to hack on React to see if I can add a command to refresh the whole app
your react-refresh work triggered me to work on my vdom stuff again. got it into a state where I might start using it for some of the shadow-cljs UI stuff. would be nice to get rid of react completely 🙂
now also has "hooks" although kinda different. can't come up with a different name though 😛
maybe you fine folks have an opinion on this. I'm trying to decide the best way to define event handlers in my library. the goal is to have events "declarative" in the code that generates the actual event. so instead of creating a function you just create a vector of data.
so experimenting defining them in the component definition. currently at 2 different approaches
(defc dummy1
{:init-state {:num 0}
::inc!
(fn [env e]
(sac/swap-state! env update :num inc))}
[props {:keys [num] :as state}]
[]
(<< [:div
[:button {:on-click [::inc!]} "click me: " num]]))
(defc dummy2
{:init-state {:num 0}}
[props {:keys [num] :as state}]
[::inc!
(fn [env e]
(sac/swap-state! env update :num inc))]
(<< [:div
[:button {:on-click [::inc!]} "click me: " num]]))
the second vector after [props state]
is "magic" for hooks. you can think of it as a special let if that helps
(defc dummy2
{:init-state {:num 0}}
[props {:keys [num] :as state}]
(let [::inc!
(fn [env e]
(sac/swap-state! env update :num inc))]
(<< [:div
[:button {:on-click [::inc!]} "click me: " num]])))
(defnc my-refreshed-component
[props]
(let [[count set-count] (react/useState 0)
[name set-name] (react/useState "React Refresh")]
;; kept it's state!
($ react/Fragment
($ :div {:style {:background "pink"}}
($ :div (b/greet name))
($ :div ($ :button {:onClick #(set-count inc)} "+ " count))
($ :div ($ :input {:type "text"
:value name
:onChange #(set-name (.. % -target -value))})))
($ :br)
($ z/component {:name "child in another file"})
($ :br)
($ z/memo-component {:name "memoized child in another file"}))))
(defc my-refreshed-component [props]
[[count set-count] (react/useState 0)
[name set-name] (react/useState "React Refresh")
::inc! #(set-count inc)
::set-name! #(set-name (.. % -target -value))]
(<< [:div {:style {:background "pink"}}
[:div (b/greet name)]
[:div [:button {:on-click [::inc!]} "+ " count]]
[:div [:input {:type "text"
:value name
:on-change [::set-name!]}]]]
[:br]
[z/component {:name "child in another file"}]
[:br]
[z/memo-component {:name "memoized child in another file"}]))
basically the first let you pretty much always have anyways becomes "special" with "hook" semantics
can't differentiate between a bound symbol and a function created inline via :on-click (fn [e] ...)
the main reason is that I want declarative events though. easier to translate for server-rendered code if there isn't (fn [e] ...)
all over the place
I think having a special “let” block is nice for setup that gets run on each render. I keep dancing with the idea of creating my own special let
macro for certain purposes
FWIW, I think on the surface it’s feasible to do enough static analysis at macro-time to determine values (like functions) that could be automatically memoized to maintain identity across renders
if you have some way of determining when e.g. an effect or render should trigger through some other means, like a signal graph, then you don’t need to call it on every render
I think where the friction starts with that approach is when you want to do something like React’s Concurrent mode. you have to figure out where scheduling all the work occurs.
if you let every state be mutated and trigger a re-render ad-hoc, then you either need to implement scheduling in the signal graph (not the component tree like React has), or you risk having state and what’s rendered diverge in degenerate cases
(defc dummy4 [{:keys [id] :as props}]
[{:keys [text]}
(-> (js/fetch (str "/some/" id))
(.then #(.json %))
(.then js->clj))]
[:div text])
actually it is all a whole lot simpler than React overall since I can do magic like this
so the model they came up with only looks like that because it is something people can actually write
although I'm not too convinced about that given the manual [all, the, deps]
args you need to construct
but they are exploring babel plugins and shit like that for that if I read that correctly somewhere
scheduling is about more than just fetching data (though it helps a ton with that). it also has to do with things that take up a lot of CPU. Concurrent mode allows React to prioritize certain renders higher than others, pause or abort them and restart them later
yeah the deps args stuff with hooks is tiresome but something we can just compile away
parent node can "suspend" child updates until all ready (at some point, still pending)
I'm familiar with how react works ... there isn't anything in there that this can't do eventually
I’ve been dog-fooding hx on my own REBL clone; sounds like shadow-cljs’ UI is a good use case 😄
is there a way to make shadow-cljs export everything in my code that isn't marked as 'private'?
adding the ^:export metadata to everything seems a bit tedious or possibly brittle
i'm using clojurescript to share schema code between the backend and frontend
so i'm consuming this from regular javascript
and basically every schema definition in a namespace should be available to the javascript consumer
to answer your question: no there is no way to make it export everything currently but that doesn't mean the couldn't be 😉
a single schema definition is just a var
we end up with a namespace that has a bunch of 'schemas' like User, Email, BookingRecord...
and then from js we take json blobs and coerce/validate them against a given schema
so in js its 'import * as schema from 'schema.general' followed by 'coerce(jsonBlob, schema.BookingRecord);'
(what acronym is DCE btw heh)
well you could do it in a build-hook but since none of the api for that is documented it wouldn't be too easy I guess 😛
yeah we want to prevent that entirely
since this is like a utility library most of it will look 'dead'
well i suppose i can add export tag to everything...
we've been using this for awhile, we were just using the 'compile' target instead of the 'release' target. i was trying to bring our bundle size down by switching to release and that breaks everything heh
well we actually wrote an internal macro for building most of these schemas
so thats not a bad option actually
ok let me try that
@thheller i regularly have small isolated/contained front-end projects pop up, and very much enjoy experimenting with alternatives when youre looking for external feedback (`hx` is another im excited to play with @lilactown). events as vectors seems like it could lead to some interesting datalog compatibility… i appreciated a lot of the ideas in factui
, but thats unmaintained last i checked
I'll let you know as soon as I'm comfortable with the code. there are still some cases I want to figure out first
40.9 KB
todomvc build looks promising 🙂 no more chunky react-dom nonsense 😛
going through some of the advanced optimized code to find obvious code issues makes the appreciate the closure compiler so much more
i havent dug into the advanced output itself enough to build an intuition of what it really does, but the artifact size difference alone is enough to instill a deep sense of appreciation for whatever its up to down there