@agile_geek: how are we doing for ClojureBridge attendee sign-ups? Do we need to do another reminder? Did anyone contact the LJC about the event? Thanks.
morning
@jr0cket: don't think anyone contacted LJC but last time I looked we had 31 sign ups out of 40 and I know of at least one other who is thinking about it.
Oh, and Good Morning to everyone.
Morning @agile_geek
I’ve an early morning question about typical clj/cljs development workflow. Is lein figwheel
or lein ring server
or other more typical? I ask as I’m currently converting https://github.com/paulspencerwilliams/reframeonheroku/blob/master/project.clj to support uberjar deployment to learn the process.
I get confused as the reframe template suggests lein figwheel
as dev mode, and lein cljsbuild
for prod build, where I’m presuming I should move this difference to lein profiles, invoking figwheel / cljsbuild implicitly? Then lein ring server
or lein uberjar
would run dev version, or compile production version?
Question for the day: Should an organisation with a number of Clojurescript teams try and make a 'registry' of components that can be reused?
My personal answer is that whenever I've seen this kind of reuse in the 'micro' attempted it costs more than it saves as the components tend to be different enough from one use case to another to diverge and the effort in determining a component exists already and learning how to use it is often greater than the effort to write it from scratch.
@paulspencerwilliams: Bearing in mind I only have toy projects.. I tend to start two repls, start the server in one and start figwheel in the other.
@agile_geek: http://udidahan.com/2009/06/07/the-fallacy-of-reuse/
For instructions on how to start figwheel REPL using nREPL see here: https://github.com/bhauman/lein-figwheel/wiki/Using-the-Figwheel-REPL-within-NRepl
@paulspencerwilliams: exactly!
I raised the reuse in components question because my current client is trying to do this and I think it's not useful.
morning
@agile_geek: Reusable software is, as idiomatic in Clojure, done as abstract, small libraries that know nothing of usage problem domain. eg Ring, Korma etc. They are reusable as aren’t related to business.
@agile_geek: My opinion is the only way to make ‘reusable business software’ is to use a SOA / microservices where the code isn’t reused, rather a published service is reused.
@paulspencerwilliams: I had a similar question last week and @mccraigmccraig pointed me to https://github.com/martinklepsch/tenzing
that worked quite well for me so far.
@paulspencerwilliams: I think exactly the same
Cheers @thomas, will read.
@agile_geek: no :simple_smile:
So here’s a question… if I use lein ring uberjar
, should this pick up the :uberjar lein profile? Specifically, lein ring uberjar
is not compiling my cljs as I would have expected:
:uberjar {:aot :all
:omit-source true
:source-paths ["src/clj"]
:ring {:handler reframeonheroku.handler/handler}
:prep-tasks ["compile" ["cljsbuild" "once"]]
:cljsbuild {:builds [{:source-paths ["src/cljs"]
:jar true
:figwheel false
:compiler {:optimizations :advanced
:main ^{:skip-aot true} reframeonheroku.core
:output-wrapper false
:asset-path "js/out"
:output-to "target/classes/public/js/app.js"}}]}})
oh, think I’ve found the issue. :uberjar was not in :profiles Opps.
dyu not have to chain lein tasks like lein do cljsbuild, uberjar
to get both a cljsbuild and an uberjar ?
@mccraigmccraig: I’m not sure. It didn’t work but CLJS compilation did happen. Lots...
reframeonheroku willlein ring uberjar
Compiling reframeonheroku.core
Compiling reframeonheroku.handler
Compiling reframeonheroku.core
Compiling reframeonheroku.handler
Compiling ClojureScript...
Compiling "target/classes/public/js/app.js" from ["src/cljs"]...
Successfully compiled "target/classes/public/js/app.js" in 8.714 seconds.
Compiling ClojureScript...
Compiling ClojureScript...
Compiling ClojureScript...
Compiling ClojureScript...
Compiling ClojureScript...
Compiling ClojureScript...
Created /Users/will/src/reframeonheroku/target/reframeonheroku-0.1.0-SNAPSHOT.jar
Created /Users/will/src/reframeonheroku/target/reframeonheroku-0.1.0-SNAPSHOT-standalone.jar
Narnia:reframeonheroku will$ java -jar target/reframeonheroku-0.1.0-SNAPSHOT-standalone.jar
2016-02-08 10:08:39.674:INFO::main: Logging initialized @2361ms
2016-02-08 10:08:43.815:INFO:oejs.Server:main: jetty-9.2.z-SNAPSHOT
2016-02-08 10:08:44.083:INFO:oejs.ServerConnector:main: Started ServerConnector@1419d047{HTTP/1.1}{0.0.0.0:3000}
2016-02-08 10:08:44.084:INFO:oejs.Server:main: Started @6772ms
if cljs compilation happened, i guess the uberjar
task has cljs knowledge baked in then
@mccraigmccraig: that doesn’t sound plausible though does it?
@mccraigmccraig: actually, I think it is supported as there’s the :jar true and :hooks [leiningen.cljsbuild]
https://github.com/emezeske/lein-cljsbuild/issues/213
@paulspencerwilliams: yeah, hooks would do it
curiously i've never tried to distribute cljs output in an uberjar - i've always served it from elsewhere for production
@mccraigmccraig: there’s also :prep-tasks ["compile" ["cljsbuild" "once"]]
@mccraigmccraig: this is only a small application without need for scaling.
there's scaling - but also that the cljs part of an app often changes without any api changes, so it's convenient to be able to just push some js to S3 or something without having to re-deploy the uberjar
agreed
@mccraigmccraig: I like the scaling idea..I can see having independent deployment mechanisms for client and server being useful
@agile_geek: I think re-use is a pull thing, not a push thing. All management should be doing is creating the right environment for re-use to happen. All attempts to 'curate' a blessed area of 'reusable' components/libraries completely fails, because it's push
@agile_geek: therefore, it's quite appropriate for an org to adopt something like GitHub (public or firewall-install), and wait for re-use to happen
Clojure development today would be unimaginable without re-use, we're doing it all the time. If the organisation has some specific aspects (e.g. a specific security or single-sign-on technology) it makes sense for people not to have to write everything from scratch
@malcolmsparks: agree on the pull thing. I also believe in the 3rd time rule.
With all attempts to standardize you should never adopt a zero-tolerance approach but only coax people towards the standard and allow those who resist the chance to do their own thing - balance between diversity (which is a form of research, continually seeking out the next thing to standardize on)
and standards/conventions/idioms (which are valuable too)
too much 'optionality' leads to balkanisation, too little leads to paralysis
@paulspencerwilliams: 3rd time rule? is that a DRY thing?
@malcolmsparks: yeah, only on the 3rd time of reusing a thing do you accumulate sufficient knowledge to make it A Thing.
https://en.wikipedia.org/wiki/Rule_of_three_%28computer_programming%29
I think that's a minimum, I heard a similar thing on Drunk and Retired where Charles Lowell said '4-5'
And there's a school of thought that says making it 'a thing' is a bad idea anyway: http://number-none.com/blow/john_carmack_on_inlined_code.html
#tradeoffs
yep, inlining is my favourite refactor. I really liked that clojure article maybe 6 months ago about inlining, to avoid having to name things.
and inlining isolates you from someone changing the (common) function and breaking your code :simple_smile:
it doesn't isolate you from someone 'refactoring' your inlining though 😞
and de-duplication also increases coupling - that's bad too!
@malcolmsparks: I agree. I think what's disturbing me about the org I'm talking about (who are using React.js not cljs BTW) is the size of component reuse and the 'enforcement'. They are talking about building reusable UI components across multiple teams and as this will be pushed on them I suspect it will end in teams spending a lot of effort looking for a component to find the one that's close but not quite what they need. That will lead to them spending a lot of time changing the original component and regression testing or they write their own anyway.
@agile_geek: yeah - I think unless re-use happens 'naturally' it is to be avoided, even discouraged
natural re-use is the only kind worth having
but you have to make sure your environment isn't simply putting up obstacles to natural re-use
and thereby starving it
Cool. Glad to have opinions on this. I suspect they will bulldoze the top down approach anyway but I want to make them aware of the dangers.
Agreed on the no-top-down thing
It has to be easier to re-use than not, or what’s the point?
Principles & guidelines are useful to centralise
I think of it a bit like standards. The standards body specs & may provide a reference implementation - but as long as a consumer meets the spec, implementation is up to them
So I think I’m progressing in my uberjar exploration. Am I right in thinking that uberjar copies all source into the target jar file, as well as compiled stuff?
And further, where is the idiomatic place for resources? where are these typically deployed to, as what I need to do is copied static files (index.html + css), and merge with the compiled cljs -> js output..
So, I purchased and read the first chapter of Web Development with Clojure and I'm impressed. I've created a few ring/compojure sites/services, and had a play with Re-frame but not linked it all up together well. This book seems to line everything up, and use the repl far more than I typically do. I'd not really considered using it to start server. I've typically been too short lived process / tdd over how I do things coming from ruby/java/c#.
@paulspencerwilliams how up to date is the book?
Not greatly, 2 years old so useful for principles, overarching approach rather than library reference etc.
it's all about the repl !
Yeah, i've used repl for playing around with code but not as the centre of my workflow. This books shows the power.
So tight feedback
@paulspencerwilliams: i'm using @jarohen 's yoyo atm to support this, though i'll port to https://github.com/jarohen/bounce as soon as i get a moment... it/they give you start!
stop!
and reload!
functions which you can use from the repl to start/stop/reload your app... https://github.com/stuartsierra/component gives you something similar (though i don't like the way way its protocols infect everything)
I've not tried components yet though it's on the radar. I get so little time to play :-/
I stumbled across an article ages ago that covered the idea of "repl driven development"
haven't been able to find it it since.
my process is repl driven,.. when things have solidified a bit i go and backfill with some tests, but i find starting with tests a bit like treacle wading
i would really like some static analysis too. bring on https://github.com/LuxLang/lux