Here are a few things I've picked up working on a large Clojure/Clojurescript 
app the last several months.  Some of this is just personal opinion or what 
works for me, so as usual YMMV.

1) Reagent vs Om - I went back and forth (several times) between these two 
early in the project.  I'm using Reagent now, but I have no qualms about using 
Om if it fits the app better.  There are lots of factors of course, but for me 
the decision now comes down to this - if it makes sense for the app to store 
all the state in a single atom, use Om.  If not, use Reagent.  For my current 
app, multiple atoms is a more natural fit, so Reagent has been a good choice.

Not that you can't use a single atom with Reagent, it's just less convenient 
dealing with deeply nested data without the benefit of cursors, and you lose 
the performance advantage (i.e. with a single atom, any change to any part of 
app state will cause every component that reference any part of app state to 
re-render).  Sean Corfield has introduced a pull request to add cursor support 
to Reagent, but I haven't tried it (I just don't have time to be messing with 
various forks - once it makes it into Reagent proper, I look forward to trying 
it out).

2) CSS/JS frameworks - I started off using Bootstrap, then switched to 
Foundation and I'm much happier with the results.  It just seems cleaner, and I 
am finding it easier to create semantic classes, which lets me avoid putting a 
billion classes on each item in my markup, plus lets me shrink the CSS file by 
cutting out unused stuff.  One cool thing about Foundation is that if you are 
only using their mixins to create semantic styles, you can set a flag to turn 
off generation of all the presentational classes, which makes the generated CSS 
tiny (I'm targeting Cordova, so the less markup/CSS, the better).  

With any framework, I avoid their JS components and just use the 
markup/styling.  I did try Om-bootstrap (twice actually) and each time I could 
never get even the most basic examples working, I think it was just too 
immature back then.

When you think about how these frameworks work, often times we can do a lot 
better using the power of React.  For example, consider the ubiquitous 
drop-down menu.  In a framework like Boostrap/Foundation, the implementation is 
basically the same.  The markup is usually a <div> with 2 inner <div>'s, one 
for the always-visible part of the menu, and one for the menu itself, which is 
hidden to start with.  The displaying of the menu is usually toggled by adding 
a CSS class.  So while this is easy enough to do in React, another approach 
that's more "Reacty" is to only generate the menu markup when it is visible, 
rather than always creating it and hiding it until needed.

That being said, often times I do just use the traditional approach and toggle 
visibility using styles for one specific reason - animations.  There are some 
libraries for doing animation with React, I just haven't had time to look into 
them, and it's SOOO easy with CSS, not to mention one of the most common 
"performance tips" you see for Cordova is to use CSS animations because they 
tend to be hardware-accelerated on mobile browsers.  So in general, when I need 
an animated effect for a menu or panel sliding in versus just appearing, I 
stick with the CSS approach, otherwise I do it the React way and just generate 
the markup I need for the current application state.

3) JS components - so a lot of those components that come with frameworks can 
be problematic with React, and like I said before emulating or replacing their 
functionality is easy to do in a lot of cases.  But there are times when you 
REALLY need to integrate a complex component - a D3 chart, a calendar control, 
ACE editor, etc.  The way you do this with React is to let React create the DOM 
node for the component, then tell React to forget about it and never update it. 
 Check out this blog from Robert Stuttaford for a great detailed 
explanation/example - 
http://www.stuttaford.me/2014/08/10/om-interop-with-3rd-party-libs/

4) Cross-browser - For the DOM and event stuff, React is the driver here.  You 
would still use the Google Closure library for things like accessing the 
browser history, AJAX, and there are some nice general utilities in there for 
stuff like date/time handling.  Most of these things have 3rd party libraries 
available that simply wrap Google Closure, so you can avoid the direct JS 
interop code.

Just don't try to use the Closure library to do stuff that React is in control 
of.  I've never actually tried it, but for example say you grab a ref to a node 
React manages and then use Closure to register event listeners on it or 
manipulate it in some way, bad things are bound to happen (at best, React just 
overwrites all your changes on the next render cycle, at worst ???).

5) IDE - I started using Lighttable and it's still working pretty well for me.  
It does sometimes crash after several days of heavy use, but I'm in the habit 
of using an NRepl connection instead of letting Lighttable create its own 
connection, so when it crashes I just restart and connect to my still-running 
REPL and I haven't lost anything.

I've played around with Cursive and I really like it and would like to switch, 
but what keeps me with Lighttable is the Clojurescript REPL works so well and 
it's trivial to get it up and running.  I keep hearing stories of how hard it 
is to get a browser repl working in just about every other environment, but 
with Lighttable, it "just works". 

6) Websockets - for various reasons, I'm using Firebase right now (this is 
temporary, but working quite well).  Before that I was experimenting with Sente 
and I had a contractor working for me that implemented some stuff using vert.x 
(he pulled out just the distributed event bus piece, so we didn't have to run 
the whole stack).  Both of those solutions worked very well.

7) cljsbuild - of course lein cljsbuild is the way to get started, and that's 
what I'm still using.  But climbing up my to-do list is to look into 
shadow-build.  It's supposed to be better at building multiple targets from a 
single code base, which is something I need (i.e. I have 3 different web apps, 
with shared components between them, and I want to generate distinct builds 
with just the parts needed for each app).

-- 
Note that posts from new members are moderated - please be patient with your 
first post.
--- 
You received this message because you are subscribed to the Google Groups 
"ClojureScript" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/clojurescript.

Reply via email to