This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-03-21
Channels
- # beginners (65)
- # boot (24)
- # cider (2)
- # clara (13)
- # cljs-dev (45)
- # clojure (48)
- # clojure-dusseldorf (2)
- # clojure-italy (69)
- # clojure-norway (1)
- # clojure-russia (5)
- # clojure-sanfrancisco (1)
- # clojure-spec (51)
- # clojure-uk (34)
- # clojurescript (312)
- # cursive (5)
- # datavis (1)
- # datomic (9)
- # duct (13)
- # editors (3)
- # emacs (2)
- # fulcro (11)
- # graphql (19)
- # hoplon (1)
- # immutant (2)
- # jobs (7)
- # jobs-discuss (38)
- # lein-figwheel (1)
- # luminus (6)
- # off-topic (2)
- # parinfer (10)
- # pedestal (1)
- # re-frame (9)
- # reagent (28)
- # reitit (1)
- # remote-jobs (12)
- # ring-swagger (26)
- # shadow-cljs (232)
- # slack-help (8)
- # tools-deps (29)
- # unrepl (29)
- # vim (10)
- # yada (31)
also i should mention that i hate java with the passion of a thousand burning suns š that part is not rational though
Well, you know clojurescript. So while you may never use it, you also have the power to do some serious thread thrashing in the future, if you want š
just as an example of what i mentioned before, take when i first started reading documentation on core.async so I could do some remote calls. the first thing any book or online resource will say is āgo blocks run your process on a thread poolā or something like that. you know immediately thatās completely wrong, so you have a little bit of work to do to figure out whatās going on. there are often places like this where the most thorough sources are clojure oriented and so thereās a little friction. this is all i meant.
Yeah, but Clojure is an abstraction. We may all be using it on some completely different host one day, where the thing isn't called a thread pool. Your point that there is friction in the docs as a result is true though
Rich specifically designed core.async (really through CSP) to be agnostic to the underlying threading model
but I see your point, older Clojure information (and thus more Google-able) is often missing the expanded context to include CLJS
I tried to put him on the spot and I asked, "So, what's your favorite part about Clojure?"
And that's pretty much the only thing I've ever heard Guy say that I've actually understood, so it must be right š
If you are interested in the upcoming ClojureScript 1.10.x a recorded talk on it is now available https://www.crowdcast.io/e/virtual-clojure-meetup-3
Thanks a lot for this @mfikes
I think they have some sort of oauth setup with perhaps Facebook and other identity providers
what do I need to setup to use react-dom with advanced compilation?
I tried :infer-externs true
and that didn't change the outcome, only added a compiler warning
(the warning is that goog
is not defined in the externs)
looks like if I switch my call from react-dom/render
to js/ReactDOM.render
then the :infer-externs
works ĀÆ\(ć)/ĀÆ
I wasn't going to share this because I was trying to figure it out myself but the error said to report it.
java.lang.IllegalStateException: EXPR_RESULT 35 [length: 3] [source_file: /Users/wade/Desktop/rn4w/node_modules/react-native-web/dist/vendor/Animated/AnimatedImplementation.js]
java.lang.RuntimeException: INTERNAL COMPILER ERROR.
Please report this problem.
EXPR_RESULT 35 [length: 3] [source_file: /Users/wade/Desktop/rn4w/node_modules/react-native-web/dist/vendor/Animated/AnimatedImplementation.js]
Node(NAME add): /Users/wade/Desktop/rn4w/node_modules/react-native-web/dist/vendor/Animated/AnimatedImplementation.js:35:4
var add = function add(a, b) {
Parent(VAR): /Users/wade/Desktop/rn4w/node_modules/react-native-web/dist/vendor/Animated/AnimatedImplementation.js:35:0
var add = function add(a, b) {
clojure.lang.ExceptionInfo: EXPR_RESULT 35 [length: 3] [source_file: /Users/wade/Desktop/rn4w/node_modules/react-native-web/dist/vendor/Animated/AnimatedImplementation.js]
from: :boot-cljs
@grounded_sage That is an error in Closure compiling JavaScript in a Node module, not ClojureScript (https://github.com/google/closure-compiler/blob/4ea1570b891ed23395fa595362314a70b7295f90/src/com/google/javascript/jscomp/Compiler.java#L2861)
Ah I see @mfikes is this something I did wrong or because the Node ecosystem isn't quite there yet with the CLJS/Closure ecosystem?
For reference I am attempting to use the React Native for Web library.
I'm actually watching you Clojure meetup talk right now btw haha.
Dunno. But I suspect that a problem like that can be produced independently of ClojureScript, running the standalone Closure compiler against the offending JavaScript.
Ran the closure compiler against the directory and it worked
The error doesn't show when I don't require it into a namespace. So I believe it is something to do with requiring it into the namespace
Most likely an error on my end but I'm not sure what this could be. Not much written material about using NPM deps that I can find.
how do I interact with doc.on('end' ...) in order to retrieve that value in result when it is available?
i might have to just leave the js as is and rather interact with the callback function from cljs
you return it in the āendā callback, so all you need is (.on doc "end" gb)
where gb
is the function @zentrope defined above
the Buffer.
is the clojure syntax for new Buffer
which may be confusing. i actually prefer to write (new Buffer)
Yeah, pass in a function that you call once the buffer is converted, or a channel (core.async).
oh yea it i suppose you might prefer to use a channel instead of mutating the chunks
global. iām not sure what exactly you want to accomplish. but either way thatās how you deal with js event callbacks.
essentially trying to convert that code I pasted to cljs, wrapping it in a function that will return the buffer in the end callback
I donāt think you can just return the value because the wrapping function will terminate before that value is produced.
Then, in the callback, update your central state atom (if thatās what youāre doing).
the atom is going to be the most straightforward translation because mutating a global is what the original pasted code does
although it occurs to me that you probably want to mutate the javascript object itself
In a react-ish browser app, thereās usually a āstateā atom from which the UI is generated. If youāre doing some sort of node thing, then ā¦ I donāt know.
this is trivial in pure js as all you have to do is follow their examples with use a node express app and the node http server
in order to not have to interact with javascript i've been trying to write that createBinary function with cljs instead
oh, so you're trying to build a nodejs web server using cljs, with machiatto? You are also trying to talk to a PDF generation library, which is a dependency on npm?
yeah, shadow-cljs is probably the easiest way to pull in the dependency, and use machiatto
@restenb that is the easiest way to pull in your dependency, but the builds tools have recently been including the ability to pull in npm dependencies to appear correctly in the cljs module system
you can define :npm-dependencies with macchiato too i think, i haven't looked into that
I thought macchiato was a web server resembling the ring-based clojure stuff, built in cljs for node?
the idea behind it was to provide a lower barrier of entry for people wanting to try out cljs, without requiring the buy-in of Java (with tools like leiningen, boot, clj, etc)
but if you're already at a point where you have your clojurescript compiling, than that's great
just make sure that you include your cljsbuild target as :nodejs, are you able to run your compiled code on node?
don't think you necessarily need to include it there, you could always manage your own package.json with npm
i know the pdf generation itself works, but i want to avoid saving the pdf to disk before serving it
trying to generate it into a Buffer and then returning that as the response wrapped as a stream
I'm not familiar with machiatto, but I know it follows closely to clojure ring-based servers. There should be a similar Ring Response object in machiatto with similar functions for assigning byte data to the response body
(defn file "accepts a path to a file, and returns a response with the body set to the file stream." [path] {:status 200 :headers {} :body (fs/read-stream path)})
@benzap Look at: https://github.com/bpampuch/pdfmake/blob/master/dev-playground/server.js
that's why i was thinking about keeping the actual buffer generation as js, and then wrapping the callback from cljs with a go block instead of trying to translate it
@restenb similarly, you could return the channel c
to a response, and pull out the data
Oh, right. You have to hand that response to something, rather than write to it. Ah, well.
(defn get-pdf-response [req res raise] (-> (r/file (report/create-pdf report-data res)) (r/content-type "application/pdf") (res)))
`(defn generate-pdf [content] (let [success (chan 1) error (chan 1)] (go (>! success (heavy-lifting content))) [success error]))`
doc.on('end', function () { result = Buffer.concat(chunks); callback('data:application/pdf;base64,' + result.toString('base64')); });
the callback needs to be your response, or it needs to be where you pass your result into the channel
so i'm keeping the chunks in a javascript object, it's just easier to work with javascript objects when working with javascript libraries
but essentially, this will process everything, and throw the result in the result channel, you can either pull from it with take!, which uses a callback, or you can grab the value from it within a go
block with <!
I guess the big issue is pulling the async result into machiatto, which i'm guessing uses callbacks
hi, i am working on a demo involving moving code between a client with clojurescript and a server with clojure. what would be the simplest way to get going with a basic form and a few buttons in cljs? i've used om-next a bit and while it has some big wins it doesn't seem like the easiest solution. i want this to be easy.
I wrote about how to serve ClojureScript files in development without running into weird caching issues: https://danielcompton.net/2018/03/21/how-to-serve-clojurescript
@danielcompton Cache-Control: max-age=0, no-cache, no-store, must-revalidate
and skip everything else
You wouldnāt need all of those directives, your header would have the same effect as Cache-Control: no-store
I found a noticeable page load time boost from using ETags, because the browser didnāt need to re-download the file every time
On todoMVC with re-frame + re-frame-10x it went from 2.3s to 1.5-1.7s to reach DOMContentLoaded
Just compiling a real world app now for a comparison
yeah itās a slow laptop
I'm curious how it would look with https://shadow-cljs.github.io/docs/UsersGuide.html#_async_loading
What is it about fetch
that is better for loading lots of files?
by default the closure debug loader uses script
tags. which means the browser must download and eval the code before continuing with the DOM
Why would waiting for DOM affect anything in this case as the code must be evaluated anyway before the app can do anything?
On our real world app, we get 10 second loads instead of 13 second loads
I think the next frontier for ClojureScript dev performance is HTTP2
because the browser will only open 6 requests per connection
Well for Figwheel then š
Iāll bet
The problem might be figwheel here. Last time I checked the import/reload code it loaded js files consecutively. It should instead just add all N js files as script tags and let the browser download them in parallel and then execute them consecutively
Yeah so then HTTP/2 will make a huge difference. I have it setup with openresty and it reduced it by like a factor of 3-4x IIRC
@danielcompton Iāve never had this issue bc I always have DevTool open with cache disabled š
280 reqs, 15.8 MB, 6s
No I found gzip/brotli slowed it down a bit, not by much but it's loopback so no reason for gzip I guess
I guess http2 and gzip can be done with figwheel via custom Ring handler?
and immediately breaks if you want to access from a remove dev setup, ie. not localhost if the cert is localhost
Hi there, I couldn't find a solution on following problem:
when running lein with-profile test doo phantom once
phantom fails with
ReferenceError: Can't find variable: Map
in onError
Error encountered performing task 'doo' with profile(s): 'dev,test,test'
Subprocess failed
You need to add a plus before your profile
lein with-profile +test doo phantom once
sorry for digging deeper, but it doesn't work and I am missing the clue. now it gives me
;; ======================================================================
;; Testing with Phantom:
ReferenceError: Can't find variable: Map
in onError
Error encountered performing task 'doo' with profile(s): 'base,system,user,provided,dev,dev,test,test'
Subprocess failed
Hmm, when I replied I quickly realized that my answer might not have been the root of your problem. It seems to me that the issue is not necessarily related to your build process
the way i normally call doo is something like lein doo phantom test
where test is your test cljs build
in your original text you don't seem to pass a build. Are you relying on the test profile alone?
Seems you are calling doo like the template says. My best guess is that there is something wrong in your test code. A reference error seems to indicate that, but I could be wrong. It also seems like the js compiles since you get that far, which again points to an error in the actual code. Thats the best I got, hope you figure it out. Sorry I couldn't be of more help.
There is a new guide covering the ClojureScript ns
form and all it has to offer: https://clojurescript.org/guides/ns-forms
@thheller Right, the original content was written back in early 2016, which I think was prior to string requires. Someone familiar with that feature should submit a PR covering it.
never saw that guide before. thought you just wrote it. I'll see about making a PR to add the string requires.
I did recently author the guide, but the original content it is based on is older blog posts that pre-date string requires.
I'm getting inconsistent errors across build tools and it's got me very confused.
When I require react-native-web
using NPM deps on Lumo it works fine. When I do it with Leiningen I get Undefined nameToPath for react_native_web
then when I am using Boot I get an error from the GCC.
@thheller Expanding on that, there should probably be a guide covering NPM dependencies, if there isn't one.
@grounded_sage I'd suggest you try shadow-cljs where this works much more reliably
Forgive my ignorance but what does shadow-cljs give me @thheller?
Ok cool I will definitely check it out. Can I use Figwheel etc with it?
I wanted to try to run tests on every save with cljs.main
. Here's where I'm at:
clj -A:test -m cljs.main -co "{:watch-fn lime.tests/-main}" --watch "test" -c
1 problem and 1 inconvenience.
Problem: The :watch-fn
can't be specified as a compiler option via the cli? Symbols are not resolved to functions and code (fn [] (prn "hey"))
are never eval'ed, i.e. "PersistentList cannot be cast to IFn".
Inconvenience: Cannot watch more than one path at a time?@petterik Perhaps it could be easily expanded to work like :preprocess
in :foreign-libs
(take a symbol that gets resolved to a function as in your example). I'd suggest an enhancement JIRA.
@mfikes I'm not familiar with :preprocess
, but I can create a JIRA and include your comments?
@petterik Sure. Take a peek at :preprocess
description here https://clojurescript.org/reference/compiler-options#foreign-libs
It would seem easy to have the compiler check of :watch-fn
's value is a symbol, and if so, conditionally behave like :preprocess
does.
am i missing a really obvious clojure.string/format
function? i found format
in an older cljs version, and also goog.string/format in an older gcc version
but both of them have changed; format is no longer in cljs.core, and itās goog.string.format/format ā whatās idiomatic?
@lwhorton Not saying its idiomatic, but format usage is documented here https://clojurescript.org/reference/google-closure-library#requiring-a-function
Strange. I have an old app Iāve updated deps for and suddenly āvalsā in CLJS doesnāt work.
There is a new reference page covering the stable JavaScript API exposed by the ClojureScript standard library: https://clojurescript.org/reference/javascript-api
@mfikes Iām slightly confused by that page. It says that āClojureScript defines types that have stable, publicly-consumable JavaScript APIsā but then all of the examples are in clojurescript.
The idea is that, any ClojureScript value satisfying the sequential?
predicate also defines JavaScript functions as defined on that page. Thus you can reliably use JavaScript interop to call those functions without being in a position of calling private API.
Feel free to contribute to the page to clarify. https://clojurescript.org/community/contributing_site
An converse example: If you do (.-cnt [1 2])
, then your code is in danger of potentially breaking.
I get it now. Iāll just submit a small patch. Feel free to ignore if you donāt like my wording.
Well I just mean Iāll offer my friendly suggestions however is best for you. š
So @lee.justin.m you almost have me convinced to try shadow-cljs in my project, but is there a way to integrate it into the lein build? Or will I need 2 steps to build a project? Itās a jetty backend and a Reagent frontend.
@jmckitrick shadow-cljs is in most part a replacement for lein cljsbuild, less painful in the long run I'd say, shadow-cljs prevents gray hairs
@jmckitrick Yes it is pretty nice to manage everything with shadow, but you donāt have to. You can run shadow from lein and let lein deal with the cljs dependencies (you still deal with npm dependencies using normal tools and a package.json) https://shadow-cljs.github.io/docs/UsersGuide.html#Leiningen
I havenāt done the lein integration so you should hop into #shadow-cljs for help if you get stuck
btw to answer the question, you need 2 steps to build a project, with or without shadow-cljs given that you're useing clojure and clojurescript. I actually don't build the clojure, just start it with lein ring plugin, but you can and some recommend that you build clojure into a .jar and start it all with java -jar
Iād really miss the figwheel integration. Especially with cider.
but cider is still bit more manual at this stage, you'd need to require nrepl yourself
Well, I get the hot-reloading, plus cider integration lets me jump around my code like regular clojure.
you get hot-reloading with shadow too. heās got his own implementation that works great and gives you the heads up compiler errors and all that jazz
I saw them in the terminal, but not in the browserā¦.
i donāt know about emacs, but now that i switched to cursive i get full integration (docstrings, jump-to-definition, etc.) so I know that shadow is at least capable of those things (doesnāt work with atom, sadly)
I just built the project 5 minutes ago š
I installed shadow about a week ago.
maybe we should take this to #shadow-cljs but basically you get error that is printed in the terminal but not into the browser?
correct