This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2020-04-10
Channels
- # announcements (2)
- # babashka (20)
- # beginners (381)
- # calva (16)
- # chlorine-clover (21)
- # cider (1)
- # clj-kondo (18)
- # cljs-dev (107)
- # cljsrn (2)
- # clojure (161)
- # clojure-dev (5)
- # clojure-europe (2)
- # clojure-losangeles (3)
- # clojure-nl (3)
- # clojure-uk (35)
- # clojurescript (22)
- # conjure (48)
- # cursive (8)
- # datascript (11)
- # datomic (6)
- # figwheel-main (10)
- # fulcro (85)
- # hoplon (112)
- # jobs (1)
- # kaocha (5)
- # luminus (5)
- # malli (1)
- # off-topic (96)
- # onyx (1)
- # pedestal (1)
- # perun (1)
- # reagent (5)
- # reitit (1)
- # shadow-cljs (34)
- # specmonstah (1)
- # sql (6)
- # tools-deps (3)
- # xtdb (23)
https://github.com/facebook/react/pull/18449 not sure if relevant, React seems to have switched to Closure compiler for compiling down to ES5
relevant for people who are militant about their dependencies (which is generally a good idea)
it doesn’t look like they ship closure-y source so it’s not like we can treat it as non-external, right?
so as long as people grab libraries willy nilly - then you're stuck w/ Webpack or whatever build mudball de jour
that said given how we've done things where we do have most of the stuff in place to DCE node_modules via Closure
I haven't looked at the most recent React releases, but at some point React created bunch of methods and properties dynamically. Even if you don't use the methods from your own code, React uses ["foo"]
when declaring them dynamically and .foo
to refer to the same methods in other places, so externs are required to optimize React code. (Not sure if this is relevent for this discussion, just note about React being Closure compatible).
@juhoteperi yeah that was years ago at this point - I know that FB has been using Closure to optimize their own React usage for a couple of years now
Yeah, the last related fixes to Cljsjs extern file where 3 and 2 years ago
But these problems weren't also very obvious to see, like 95% of Reagent tests passed and then a few test cases where broken due to these problems.
iirc, React team reached to Closure people at some point to get a couple of switches in the compiler that makes advanced mode less aggressive specifically for React
I think I addressed all the reported externs inference issues - let me know if I missed anything
if you all some low hanging fruit issues you'd like to see added to the next release let me know
Maybe these - https://clojure.atlassian.net/browse/CLJS-3195 - https://clojure.atlassian.net/browse/CLJS-3086 - https://clojure.atlassian.net/browse/CLJS-2863 These are small - https://clojure.atlassian.net/browse/CLJS-3106 - https://clojure.atlassian.net/browse/CLJS-3105 - https://clojure.atlassian.net/browse/CLJS-3102
here are my current thoughts about the coming changes - https://gist.github.com/swannodette/919ef8fb51e7ee91b5f3ab643c4b3e55
feedback welcome, it's pretty simple - and I have another project that more or less confirms that it works
I can’t quite tell exactly what the motivation is yet. it sounds like it would be really useful for people who want to consume their CLJS code in storybook, or use with react-native. is that close to the mark?
I'd be interested to see a working example if you do find a way to use Storybook with CLJS code.
@lilactown it removes nearly all the steps (some error prone) for people who want to use some random lib
but more importantly it provides a portable way to create clojurescript libs that depend on node_modules
I didn’t understand anything in that gist to be about clojurescript libraries. the bulk of the content seems to be about a :bundle
target? I’m not sure yet how that rolls into libs
I suspect this already works for shadow-cljs but shadow-cljs isn't the standard tool chain so it's not really much of a win - not portable
@lilactown because we don't need to talk about anything else other than :bundle
hmm. I guess maybe I’m out of my depth? I don’t understand yet the link between a :bundle
target that (by the gist)
> any tool that handles Node.js `require` can build ClojureScript - webpack, metro, etc.
to the problem of libs that depend on node_modules or using some random lib.
I’m looking at this from several perspectives:
• I’m a ClojureScript library author whose most popular libs depend on node_modules
. How does this effect my libraries?
• I’m an application developer who uses many node_modules
libs and uses many ClojureScript libraries that wrap node_modules
. How does this effect my toolchain and dev experience?
perhaps, if I’m inferring right, it means that instead of: webpack creates a big ball of JS that then GCC needs a bunch of externs / must export to the global context…
it would go the other way: we would emit a bundle of CLJS code with holes, that expects the node_modules
deps to be require(…)
able and then feed that into webpack so that it can resolve the require
s to node_modules
and have webpack emit our final bundle
I'm a ClojureScript library author whose most popular libs depend on node_modules. How does this effect my libraries?
this category does not exist
I'm an application developer who uses many node_modules libs and uses many ClojureScript libraries that wrap node_modules. How does this effect my toolchain and dev experience?
fewer steps, less boilerplate when working the standard compiler
@lilactown right but nothing I said talks about webpack specifically - in fact not interested in automating that part at all
this is a good area for people to extend ClojureScript to make a shadow-cljs like experience + Figwheel or custom build setup or whatever
there are aren't any portable ClojureScript libraries that depend on node_modules
today that don't require a lot of manual project-specific non-reproducible steps
that’s very true. I’ve had to maintain a separate branch of https://github.com/Lokeh/helix for cljs/figwheel-main, since the main branch implicitly relies on some behavior in shadow-cljs. it makes me feel bad, but it’s what I use both at work and for hobbies so it makes sense to spend most of my time with that
so this is about establishing a normal way to do this - shadow-cljs supporting the standard way along w/ it's own way shouldn't be hard
yeah, my case isn’t exactly related to node_modules
but it’s a sort of second-order effect
I also think that paving the pathway for consuming CLJS code from any JS bundler is a really good idea when it comes to incremental adoption. I was lucky with the projects I’ve been on the last few years, because we were able to start greenfield with CLJS.
trying a bottom-up incremental adoption of CLJS is a harder sell, since there’s so much boiler plate and additional stuff outside the happy path to get it running in an existing project using webpack or rollup or whatever the bundler du jour is
looking at your project, I would say that's directly related to the node_modules
problem 🙂
@lilactown w/ my proposal above the caveats about non-shadow tools just go away
then anyone can install the required npm deps, it doesn't matter what tool they finally end up using
I still need to maintain a separate branch, unfortunately, due to some differences between how shadow and vanilla cljs handle JS in-project. that’s what I meant by second-order effects.
don’t need to get into that now, not relevant and I don’t completely understand it myself
with shadow-cljs, I can use ES6 import/export but it doesn’t work as well with Closure-style JS (for some reason I haven’t spent the time to diagnose). with cljs, I couldn’t get the same ES6 import/export and require syntax to work, so I used goog.provide
huh - ok - honestly if you need some JS and you want it to always work for ClojureScript writing plain old Google Closure JS is probably wise - https://github.com/cognitect/transit-js/blob/master/src/com/cognitect/transit.js, is worth studying if you want to make it slightly less tedious. especially if you're not writing a lot JS it's not worth it to complicate the build for people by writing higher level JS
yeah it’s very minimal - the only reason I did it was to try and get better interop with native classes
trying to create classes the ES5 way doesn’t quite have the same behavior when the browser actually has native classes, so my hope was that I could rely on GCC to compile down the helper fn to either ES5 or actually use real classes depending on what the user wants to emit
this way from my cljs code I can just spew:
(helix.impl.class/createComponent
React.Component
#js {:constructor (fn [this] (set! (.-state this) #js {:foo "bar"}))
:render (fn [this] ,,,)}
nil)
@lilactown deps.cljs
should be able to help you here too, but this feature is not under heavy usage - I haven't had a need myself - so I can't say more than we test basic stuff and that appears to work
while I have your attention about this, would you ever consider a patch that added a form that emitted a class
? 😅
it's worth thinking about since that is a well known pain point - the problem is that you would need to transpile the generated JS again with Closure if we're going to maintain the nice fact that ClojureScript only generates ES3
people keep talking about generating higher level JS but I really see only tradeoffs and most of them not in favor
@lilactown https://clojurescript.org/guides/javascript-modules, the beginning of this explains what you need to do
:foreign-libs [{:file "helix/impl/class.js" :module-type :es6}]
should theoretically work for you in your deps.cljs
I have reported issue for this some time ago https://clojure.atlassian.net/browse/CLJS-2399 and seems not resolved
yeah, a lot of higher level features have a relatively minimal impact on applications, but a considerable impact on project maintenance
yep. tho it was interesting to see what people were talking about re: future async/await perf benefits
but that’s even a whole other level of effort, since AFAICT it would require so much work to make the way that CLJS handles things like do
work with the function-boundary behavior of async/await
class
is one that really bites me since more and more browsers are supporting it natively, and so interoping with them becomes more of a pain point.
it’s minimal in most application code, but the places you need it you need it and you can’t get away with an ES5 mock of a class
people keep talking about async/await perf but honestly I find such talk meh esp. in browser context
Node.js really isn't that interesting for server IMO if you're already doing Clojure anyway
I think some work on codegen for core.async is all that it really needs - it's not that slow
@lilactown re: class
I'm not against this if it's selective
i.e. if you use defclass
we'll generate ES6 and do a second pass w/ Closure on that file
it doesn't sound like a particularly hard project (I already have a Closure transpile in ClojureScript) - if you want to take a look at this be my guest
it’s not an immediate need - my Closure JS workaround seems to work OK - but it would be really nice to delete that code from my projects
how does this look? https://clojure.atlassian.net/browse/CLJS-3226