This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
Are people sharing the “markup” between hiccup and sablono?
so, Hiccup and Sablono use the same data structures
i have a server page that generates the html via hiccup
and i’m building out a React component is the data structure is the same
granted there is no functionality in the React one yet
and I was struck that they were the same (so far) and it made me wonder if people are sharing them
my guess is no, because as i dig deeper into this the React one will diverge
https://clojars.org/cljs-npm/lein-template has been refined to the point where I don't have to think much about tooling when I just want to do some nodejs programming in clojurescript.
is there a built in way to do UUID generation in clojurescript? or do I need to require a closure lib?
Is there an edn processor for clojurescript? Oh, there is https://github.com/cognitect/transit-cljs
That's not EDN, that's transit. It's different. If you explicitly need to read EDN then use this - https://github.com/clojure/clojurescript/blob/master/src/main/cljs/cljs/reader.cljs#L460-L466
Otherwise transit is probably a better choice - it's faster in the browser due to using a compact JSON encoding.
cljs.reader/read-string
reads a clojurescript object which is a superset of EDN. If I wanted to stick to strict EDN, it might cause a problem. transit-cljs looks like a better alternative although I don't know if it's good on nodejs.
@jaen: Do you know how to prevent javascript programs from calling a two argument cljs function with one argument? npm modules written in clojurescript exposes cljs functions to plain javascript.
IIRC cljs.reader/read-string
reads just EDN as opposed to it Clojure counterpart, which can read a superset. Take a look at the dosctring for the read
function above: Only supports edn (similar to clojure.edn/read)
.
cljs.reader/read : Reads the first object from a PushbackReader. Returns the object read. If EOF, throws if eof-is-error is true. Otherwise returns sentinel.
Maybe the regex they use to extract the documentation got tripped up by a double newline in it?
I don't think there is a syntactic difference, but Clojure can be made to write out EDN Clojurescript won't understand - for example
boot.user=> (defrecord Test [a b])
boot.user.Test
boot.user=> (pr-str (Test. 1 2))
"#boot.user.Test{:a 1, :b 2}"
boot.user=> (read-string (pr-str (Test. 1 2)))
<#C053K90BR>.user.Test{:a 1, :b 2}
This here gives more information, I think - http://stackoverflow.com/questions/24661655/clojure-clojurescript-clojure-core-read-string-clojure-edn-read-string-and-c
@jaen : Have you checked out my cljs-npm template? It is a fast way to develop nodejs application and launch a cljs REPL. If you know a faster way to launch a CLJS Repl, let me know.
I think you are able to register custom tags though - so you would be able to extend the EDN reader to read types you need, it's just not in the basic feature set (since there's now way for the library to know which types in your Clojure code would correspond to which types in your Clojurescript code).
And one remark more - if you really don't need to use EDN for some reason (as in you are already talking to a service that understands only EDN) I would prefer to use transit
Mainly because of the performance advantage in JS environments - EDN has a parser written in Clojurescript which runs on the Javascript VM, whereas transit due to it's JSON encoding can re-use the native code of JSON.parse
.
As you can see transit can even outperform using JSON directly - http://jsperf.com/json-vs-transit/2 - since the encoding uses only arrays, no objects.
@crocket: as for your template - I've noticed it, but didn't look into it too much, since I do Clojurescript only in the browser and not on node. I also use boot instead of leiningen. So I don't really know if you can do better with lein.
Without my template, you're basically stranded on nodejs. Clojurescript itself doesn't have much of nodejs tooling support.
Yeah, that is true. Most people prefer to just write JVM Clojure if they have to do the server side, so there's little interest in making that better, I suppose.
JVM Clojure programs consume at least 165MB which is not good for small daemons. nodejs daemons can consume a lot less memory. Plus, nodejs apps launch a lot faster, so they are better as command line apps. So, nodejs runtime is better for small programs.
Sure, I know what advantages using Clojurescript on node can have over JVM Clojure, but it just seems that is not an issue for most Clojure users.
And sure, "having Clojurescript work better with existing Javascript ecosystem is a non-goal" is also vexing to me (why am I forced to incorporate webpack into my builds?) but I guess that's the reason for that.
Since (cljs.reader/read-string "#cljs.user.Test{:a 1, :b 2}")
leads to an error, it seems cljs.reader/read-string
can't read a string if a tag is not separated by a space.
Let me check, but I think it's the case of "you have to register a handler for this tag" I mentioned before.
boot.user=> (read-string "#inst \"2016-01-01T09:34:29.957-00:00\"")
#inst "2016-01-01T09:34:29.957-00:00"
boot.user=> (read-string "#inst\"2016-01-01T09:34:29.957-00:00\"")
#inst "2016-01-01T09:34:29.957-00:00"
Well, it is syntactically valid EDN, it's just that it's semantically invalid unless you provide your own handler for the tag.
#js{:a 1 :b 2}
looks like a record because #js
and {:a 1 :b 2}
are not separated by a space.
never tested it but I'd stick to JSON since it is available natively just about everywhere and requires less code
ie. if you work with a browser you don't need to ship a msgpack implementation, if there even is one for js
Also, re: tags
(defrecord Test [a b])
=> nil
(cljs.reader/register-tag-parser! "cljs.user.Test" map->Test)
=> nil
(cljs.reader/read-string "#cljs.user.Test{:a 1, :b 2}")
=> #cljs.user.Test{:a 1, :b 2}
It just won't do it by default, since it can't know the semantics of your tags automagically.
I suppose msgpack transit could be more performant in JVM Clojure than JSON transit though, since it's a binary encoding, but I haven't done any benchmarks.
@jaen : If I imported an npm module via :foreign-lib, why would it still need to be on :externs?
And on the browser your best bet is to preprocess the modules out with webpack/browserify/somesuch and use as a normal, non-`:module-type` foreign lib.
But, :advanced optimization could improve performance a lot for commonly used npm modules.
Yeah, you basically have to - otherwise you will end up with megabytes of ouput which is prohibitive for web pages.
I think you want tighter integration with npm modules. One that doesn't require :externs or :foreign-lib.
Preaching to the quire there, I've dabbled in that before. But like I said, there wasn't all that much interest in that.
And regardless of that you will have to write externs, since most Javascript libraries aren't amenable to GClosure optimisations, so you have to exclude them from that and provide externs (so the compiler knows what to not rename).
Sure, and I made my own fork of Clojurescript compiler that could compile Clojurescript projects that included React and material-ui as they are published in npm, so?
If there's no interest to mainline that, then I don't see much point in doing that to be honest '
But libraries will probably break anyway with optimisations, because Javascript world at large doesn't follow GClosure optimisation guidelines
On the other hand you can exclude the libraries from the optimisation process by using them as foreign libraries
There is a possibility to write some code that could analyse the foreign library and produce externs, but I don't think that avenue was explored yet.
Sure, it could be done somehow, no idea what would be the best approach though - would parsing and analysing be good enough, or would evaluating and examining the resulting Javascript objects be required.
So, google closure better extract extern so that GClosure advanced optimization guideline becomes useless.
As for the former issue - you could try my fork to see it in action - https://github.com/jaen/react-with-modular-cljs. It uses forked Clojurescript and reagent that work with npm React package as-is. It works great with no optimisations, but as soon as you try :advanced
- React breaks.
So that is a dead-end probably and foreign libs + externs is the way to go unfortunately.
The world was created in 7 days by the god. Javascript was created in 10 days by a human under deadline pressure.
If the first web browser just embedded a scheme runtime for scripting, it could have been better.
IIRC that was the original intention and Eich was hired with "you'll be implementing Scheme in browser".
Just adding [cljsjs/nodejs-externs "1.0.4-1"]
to :dependencies
in project.clj enables me to include (def fs (js/require "fs"))
in source code on :advanced
optimization mode.
How do I run my HTTP application and have figwheel update my JS at the same time?
lein run
to start the app then lein figwheel <build name>
for the JS app - but figwheel goes to a different port
@drusellers: I think you want to start figwheel client by hand and provide it with proper websocket url to your figwheel server: https://github.com/binaryage/cljs-devtools-sample/blob/master/src/figwheel/devtools_sample/figwheel.cljs#L9
@darwin: cool, i dig in - thank you
I’m running figwheel server on port 7000: https://github.com/binaryage/cljs-devtools-sample/blob/master/project.clj#L23
and don’t use built-in figwheel server for serving my content: https://github.com/binaryage/cljs-devtools-sample/blob/master/project.clj#L20
ALL THE OPTIONS
@darwin so you have figwheel on port 7000 like the repl on some other port. It then compiles the JS files to the file system - which allows the proper application to read them and serve them.
@darwin: what is this profile :checkouts
ignore checkouts for now, that is for consuming latest versions of libraries: https://github.com/technomancy/leiningen/blob/master/doc/TUTORIAL.md#checkout-dependencies
ok, cool.
still wrapping my head around the entirety of the lein project size.
thank you for this focused sample. def going to clean somethings up in my own project.clj
to answer your question, figwheel server runs on port 7000, --AFAIK compiled files are sent as sources over the web-socket channel and eval’d in js context, filesystem not involved— <- no this is wrong, files are reloaded via urls
gotcha
so do you have to change the port you serve your app on? aka the HTTP backend?
mine is on 5000
and if figwheel is on 7000
i’ll need to then change my asset links to port 7000
figwheel’s server runs on port 7000, it serves no content, and provides /figwheel-ws end point for websocket channel
btw. this is recommended thing to do in long run, you should not use figwheel server for your content, that is there only for convenience, for people to have something to start with without messing with ring
ok, more denseness, figwheel client? I don’t see any ‘client’ type code when reading over - https://github.com/bhauman/lein-figwheel
let me study your repo a bit more
i imagine it will become clearer.
client runs alongside your javascript in your js app, when your require figwheel.client
from support project
there is also some magic how to require and start figwheel by leiningen automatically, but I don’t follow this stuff, I prefer to do that by hand myself (to understand what it does)
ok, i haven’t seen the require figwheel.client thing yet
still just barely using figwheel as a part of getting devcards stood up
also, i like the way you are merging cljbuild stuffs with profiles
because you want to do that by hand if you want to follow cljs-devtools-sample example
So, remove this (https://github.com/eventgonegood/app/blob/master/project.clj#L66) magic and go for a more hand crafted approach
yes, or alternatively leave it there and learn how to instruct figwheel client to use port 7000 in that config
ok, i can dig into figwheel a bit more, that seems like a good idea in general
it should be possilbe, because that config map is just a convenient way how to setup figwheel client via project.clj and let it start automagically
does anyone know where the docs for the rules around deps.cljs
are? Is it just every deps.cljs
file found on the classpath?
@drusellers: btw. I’ve learned that profile merging trick just recently and it really renders leiningen+cljsbuild pretty flexible, before I wasn’t able to express many configuration needs, here is another example for inspiration: https://github.com/binaryage/chromex-sample/blob/master/project.clj
yeah, that’s a neat trick. i was wondering how I could “dry” that up
I tend to combine multiple profiles via with-profile
and define common combinations using aliases for easy access from command line
just remember, for merging to work properly, the trick is to specify :cljsbuild
as map of build configs, not that alternative way using a vector
and you should include :cljsbuild {:builds {}} in “base" profile to avoid https://github.com/emezeske/lein-cljsbuild/issues/413
@darwin: gotcha!
it appears http://clojars.org is down….Is there any other repos that mirror what’s in clojars?
@adammiller: I'm not aware of mirrors, but the problem is transient. See http://status.linode.com
Yeah it seems to be back up now.
Now is a great time to support the volunteers that run Clojars https://salt.bountysource.com/teams/clojars
When you profile Clojurescript using Chrome DevTools, is it normal that the garbage collector takes more than 50 % of the profiled time?
@alexmiller: Hello, Alex! I'm very interested in the results of the survey. Can you tell when results will be ready, please?
Next week!
thanks.
FYI I made a demo for using Datomic with Hoplon that is now part of the demos project. I have just created a PR that also shows the update round trip. Uses the in-memory database for simple provisioning. So if anybody wants to get started with Datomic on Hoplon there are now a few simple examples...
@leolaporte: is it a fake account or are you really checking this out? What has prompted the interest?
How are people writing their main
functions for launching CLJS/OM “apps” - for instance I have at least 3 different “root” applications - is just conditionally “launching” them based on dom nodes the current practice? ala https://gist.github.com/drusellers/27cbd0c22217930fde27
I think I've just stumbled upon http://dev.clojure.org/jira/browse/CLJS-1444. Is there a work-around?
I see the exception handling wiki page on the clojurescript github repo but I'm curious if there is a common strategy to handling exceptions.
@drusellers: there’s an #C06DT2YSY channel
@dnolen: thanks