Fork me on GitHub

Reading through the newest DHH rants, wondering if cljs can produce import maps instead of a single bundle


What are his latest rants?


What are import maps?


If you are looking to compile to ES modules, check out the shadow-cljs :esm build, it's the only thing that currently works


more i'm just hoping to escape advanced compilation and all its nonsense


you could just bypass CLJS by directly using JS you know ;)

😄 2

CLJS advanced compilation is like lycanthropy: most of the time you don't notice it too much, it gives you abilities that others have to do a ton of work to get in other ways, and every full moon or so it causes a serious problem that only experts understand why it happened


TBH i'm on team werewolf still


we have :advanced precisely so that we don't have to worry about all the nonsense the JS world is doing 🙂 import maps or esm don't fix those things

💥 2

@U4YGF4NGM What kind of a rare but serious problem have you encountered from :advanced ? The only problem I’ve ever encountered, I think, is from missing externs.


… Which granted, is annoying the first 10 times you encounter them 🙂 After than, I learned how to type hint everything properly, and the auto-generated externs take care of that.


there was the time that names generated via advanced compilations collided with minified code from google analytics 😄


I am also now very conscious of the fact that static keywords get lifted into a global constants table, after debugging some code that used React's useMemo + a keyword for detecting when it should recompute. turns out the code was buggy, but it wasn't caught in development because a new keyword was being constructed every render; once it went to production, the keyword wasn't constructed every render which triggered the bug


@U4YGF4NGM Ah, thanks for the explanation. Was the code using references (identical? …) or values (= …) to check if it should re-render?


usememo compares objects by reference which is why it was breaking in prod (or not breaking in dev)

👍 2

I’ve had something similar happen when using memoized components where if you have nested components, the inner component would not re-render unless the outer one re-renders


But I believe it was the same in dev and in prod… so kinda different.


(let [status (if succeeded? :success :fail)
      ;; recompute something anytime the status changes 
      computed-data (react/useMemo #(expensive-computation data) #js [status])]
    ;; send the data to the API anytime it changes
    #(api/update-state! computed-data)
    #js [compute-state]))
this displays the essence of the problem, though it's reverse - in dev, this will call update-state! every render, since it will reconstruct a new keyword for status every render. whereas in prod it will work as expected

👌 2

ClojureScript needs advanced compilation


the analysis is interesting but even for JavaScript you want minification


however if your usage of JS is precise and you don't need a lot of it, and you tightly control your deps then what DHH is proposing is definitely a big simplification


we also live in a world where like almost 40% of JS dev is now in TypeScript - so I don't know


compile steps for JavaScript are never going to go away - and once your application get large enough tree-shaking and minification are must (which DHH largely ignores, but you cannot ignore it)


if you're waiting a non-advanced compiled ClojureScript - you'll be waiting for a very long time 🙂


DHH is also a maintainer and advocate of which is an attempt to move more UI behavior to the backend


he's on the "tasteful sprinkle of JS" side of things rather than building an entire app in the browser.


with all the obvious tradeoffs- I've heard mixed reviews of's UI, which uses it