This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-08-02
Channels
- # beginners (118)
- # boot (73)
- # cider (2)
- # cljs-dev (65)
- # cljsrn (18)
- # clojure (49)
- # clojure-argentina (4)
- # clojure-italy (19)
- # clojure-portugal (1)
- # clojure-russia (1)
- # clojure-spec (34)
- # clojure-uk (102)
- # clojurescript (202)
- # code-reviews (3)
- # core-async (5)
- # cursive (11)
- # datomic (25)
- # emacs (1)
- # graphql (22)
- # hoplon (6)
- # keechma (59)
- # leiningen (10)
- # luminus (31)
- # lumo (78)
- # off-topic (141)
- # om (32)
- # om-next (2)
- # onyx (6)
- # parinfer (55)
- # pedestal (3)
- # protorepl (3)
- # re-frame (8)
- # reagent (8)
- # ring-swagger (1)
- # rum (20)
- # specter (1)
- # sql (5)
- # test-check (11)
- # vim (13)
- # yada (7)
the Closure compiler is not really a compiler, it’s an optimizer. with optimizations :none, it is not called. otoh, Clojurescript is a compiler, it translates cljs to js. so with no optimizations you get the latter but not the former.
that's kind of crazy then; I would expect a clojure "cljs -> js" translator to be slightly faster
I have a hard time seeing how translating 3000 lines of cljs into js should take 40 seconds
You keep saying that, but I've never seen compile times so slow with CLJS. I'd love to see what you're compiling sometime
most of my CLJS incremental compile times are around 1.5 seconds.
@U07TDTQNL : that's not my incremehntla compile time, that's my "initial compile time"
Is that number from Boot (`Elapsed time: xx sec`) or from ClojureScript compiler (`Compile sources, elapsed site:`)?
2017-08-01 20:21:53.534:INFO::main: Logging initialized @4884ms
Starting reload server on
Starting file watcher (CTRL-C to quit)...
Writing adzerk/boot_reload.cljs to connect to ...
Writing main.cljs.edn...
Compiling ClojureScript...
• main.js
Elapsed time: 36.705 sec
That time is from Boot and includes lots of other things besides just Cljs compilation
Clj compilation of boot-cljs, boot-reload namespaces, java logging initialization, writing files to Boot temp dirs etc.
Boot has some overhead over just using ClojureScript compiler alone, or over Lein-cljsbuild/figwheel, due to tmp-dirs and pods
You can enable :compiler-stats
to check ClojureScript compiler timing: https://clojurescript.org/reference/compiler-options#compiler-stats
I think 15-20 sec from that is from ClojureScript compiler and rest is other tasks and overhead
2017-08-02 08:38:37.393:INFO::main: Logging initialized @4826ms
Starting reload server on
Starting file watcher (CTRL-C to quit)...
Compiling main.css...
Writing adzerk/boot_reload.cljs to connect to ...
Writing main.cljs.edn...
Compiling ClojureScript...
• main.js
Compile sources, elapsed time: 27768.580548 msecs
Compile sources, elapsed time: 32.27119 msecs
Writing target dir(s)...
Elapsed time: 37.437 sec
why do you care about non-incremental compiles?
should only really need to be done once a day or so
That is true also
But that does look like a bit more than it usually takes for me
practically, it doesn't matter; intellectually, I'm just curious if I can tweak it somehow
❯ cloc --include-lang=Clojure,ClojureC,ClojureScript src
179 text files.
179 unique files.
39 files ignored.
v 1.72 T=0.31 s (451.4 files/s, 65060.4 lines/s)
-------------------------------------------------------------------------------
Language files blank comment code
-------------------------------------------------------------------------------
Clojure 70 1172 611 7387
ClojureScript 51 890 198 7245
ClojureC 19 373 152 2148
-------------------------------------------------------------------------------
SUM: 140 2435 961 16780
Compile sources, elapsed time: 20190.453699 msecs
Recent releases have cut a few seconds from this already
also, I recently got a deell power edge with 2 x 6 cores + 96 gb of ram; so I was hoping things would massively parallelize, and the 'initial startup compile/run time' would also decrease
hmm, this current compile isn't even 3k loc, it's only 1.3kloc:
cloc src/
18 text files.
18 unique files.
0 files ignored.
v 1.72 T=0.05 s (334.8 files/s, 32398.5 lines/s)
-------------------------------------------------------------------------------
Language files blank comment code
-------------------------------------------------------------------------------
ClojureC 14 350 40 1152
Clojure 1 22 10 90
ClojureScript 3 20 0 58
-------------------------------------------------------------------------------
SUM: 18 392 50 1300
-------------------------------------------------------------------------------
(I have a weird setup where directories get moved around alot for different projects)Dependencies also matter, as those are also compiled
With Boot-cljs anyway, as it doesn't have persistent output-dir between runs
(set-env!
:source-paths #{"src"}
:resource-paths #{"resources/client/"}
:dependencies '[;; clojure core
[org.clojure/clojure "1.9.0-alpha17"]
[org.clojure/clojurescript "1.9.854"]
[org.clojure/core.async "0.3.441"]
[org.clojure/core.match "0.3.0-alpha4"]
[haslett "0.1.0"]
;; client support
[adzerk/boot-cljs "1.7.228-2" :scope "test"]
[adzerk/boot-reload "0.5.1" :scope "test"]
[adzerk/boot-cljs-repl "0.3.3" :scope "test"]
[pandeiro/boot-http "0.8.3" :scope "test"]
;; repl support
[com.cemerick/piggieback "0.2.1" :scope "test"]
[weasel "0.7.0" :scope "test"]
;; [org.clojure/tools.nrepl "0.2.12" :scope "test"]
;; server
;; [ring "1.6.0-RC1" :scope "test"]
;; [ring-middleware-format "0.7.2" :scope "test"]
[com.cognitect/transit-cljs "0.8.239"]
[org.martinklepsch/boot-garden "1.3.2-0"]
[cljs-ajax "0.6.0"]
[binaryage/oops "0.5.5"]
[reagent "0.6.0"]
[reagent-utils "0.2.1"]
[ring/ring-core "1.5.0" :scope "test"]
[ring/ring-jetty-adapter "1.5.0" :scope "test"]])
that looks like it can easily take 40sLein-cljsbuild and others just keep the output-dir between runs so Cljs can use the compiler cache
I COULD implement some kind of persistent cache for Boot-cljs, but improving startup time has not been a priority for me, and this would introduce some cases where the cache probably would need to be cleared manually
the other thing to mentions is that in lisps LOC is a less useful metric
A go block has way more lines of code than a when
even though they may look the same
I have a minimal boot project:
(set-env!
:source-paths #{"src"}
:resource-paths #{"resources/client/"}
:dependencies '[;; clojure core
[org.clojure/clojure "1.9.0-alpha17"]
[org.clojure/clojurescript "1.9.854"]
;; client support
[adzerk/boot-cljs "1.7.228-2" :scope "test"]
[adzerk/boot-reload "0.5.1" :scope "test"]
;; repl support
[org.martinklepsch/boot-garden "1.3.2-0"]])
merely starting up takes:
Starting reload server on
Starting file watcher (CTRL-C to quit)...
Compiling main.css...
Wrote: /home/x/.boot/cache/tmp/home/x/build/client/hxf/-60q7oj/main.css
Writing adzerk/boot_reload.cljs to connect to ...
Writing main.cljs.edn...
Compiling ClojureScript...
• main.js
Compile sources, elapsed time: 2703.131897 msecs
Compile sources, elapsed time: 33.903338 msecs
Writing target dir(s)...
Elapsed time: 12.273 sec
That seems reasonable startup speed for empty project
Is this not correct?
(ns foo
(:refer-clojure :rename {map clj-map
filter clj-filter
or clj-or
if clj-if
reductions clj-reductions}))
I get replacement warnings in figwheel when I touch the ns 😞Also: Is there a way to prevent all builtins from being included in an ns? The "differences from clojure" page says only :rename
and :exclude
are supported...
@mfikes Good point, that might be the case. I think it still goes wrong for the other vars too though, will check
The funny thing is that it initially compiles without problems, but complains whenever I change something there
map already refers to: cljs.core/map being replaced by: foo/map
filter already refers to: cljs.core/filter being replaced by: foo/filter at line 17, column 1 in file foo/core.cljs
reductions already refers to: cljs.core/reductions being replaced by: foo/reductions at line 20, column 1 in file foo/core.cljs
@mrchance That appears to be a bug in the ClojureScript compiler, surrounding the :rename
feature
The :refer-clojure is recognized and parsed correctly at least, when I put a typo in there it doesn't compile anymore...
@mfikes hrm, I’m not sure if your assessment is correct
I think :exclude
is needed, even in Clojure
2 different REPL sessions:
boot.user=> (refer-clojure :exclude [map] :rename '{map lol})
nil
boot.user=> map
#object[clojure.core$map 0x5e5b5265 "clojure.core$map@5e5b5265"]
boot.user=> lol
#object[clojure.core$map 0x5e5b5265 "clojure.core$map@5e5b5265"]
boot.user=> (defn map [])
WARNING: map already refers to: #'clojure.core/map in namespace: boot.user, being replaced by: #'boot.user/map
#'boot.user/map
boot.user=> (refer-clojure :rename '{map lol})
nil
boot.user=> map
#object[clojure.core$map 0x79ac87f2 "clojure.core$map@79ac87f2"]
boot.user=> lol
#object[clojure.core$map 0x79ac87f2 "clojure.core$map@79ac87f2"]
boot.user=> (defn map [])
WARNING: map already refers to: #'clojure.core/map in namespace: boot.user, being replaced by: #'boot.user/map
#'boot.user/map
@anmonteiro That's interesting. refer-clojure
and (ns ... (:refer-clojure ...)
have different behaviors in Clojure with respect to whether renamed symbols are still visible
@anmonteiro My guess in the above is that boot.user
is already "tainted" with core symbols, and that's why (refer-clojure :exclude [map])
doesn't really do anything about the map
that has already been referred.
You can see the same in a fresh namespace.
(ns foo.bar (:refer-clojure :rename {map lol}))
renames map
upon bringing it in. But if you first do
(ns foo.bar)
before the form with :refer-clojure
, you have map
, and then lol
.I see
makes sense
I know you can do (ClassName.) which is equivalent to new ClassName(), but I want to be able to get the actual value of ClassName (for prototype stuff)
the . indicates execution - just use ClassName without it
i'm seeing an exception trying to start an isomorphic ClojureScript app (the Node server) with cljsjs/react-dom in 1.9.845. It breaks trying to require React as a Node module (e.g., require('react')
). I've done some debugging, and in previous versions of ClojureScript, specifically 1.9.671, exports
and module
do not exist which triggers a different, successful code path at the start of react-dom.inc.js
. Looking further it appears a change to CLOSURE_IMPORT_SCRIPT
in goog/bootstrap/node.js
to how files are required is the culprit (specifically the change to use require
over nodeGlobalRequire
, which happened in https://github.com/clojure/clojurescript/commit/fc0989f1b44b97547410a2d2c807f16430b47486). Does this sound familiar, has anybody else seen this behavior, is this a legitimate issue, or am I doing something I shouldn't be doing? Thanks for the help!
@crteal I don’t quite understand your problem, but is requiring react
from node_modules
not an option?
we did some changes around Node.js bootstrapping but all it should do is not allow you to require JS modules processed by Closure
makes sense
so if you’re using CLJSJS/React, where are you doing require('react')
?
I’ve ran into this before
just install react
from NPM
@crteal this is your problem https://github.com/reagent-project/reagent/issues/296
looks like it, thank you @anmonteiro!
newbie question: are source maps supported by vanilla Node.js repl? I have source-map-support
in node_modules
but I see:
cljs.user=> (ffirst 1)
repl:13
throw e__7439__auto__;
^
Error: 1 is not ISeqable
at Object.cljs$core$seq [as seq] (/home/arichiardi/git/logpoc/out/out/cljs/core.cljs:1209:20)
at Object.cljs$core$first [as first] (/home/arichiardi/git/logpoc/out/out/cljs/core.cljs:1218:15)
at cljs$core$ffirst (/home/arichiardi/git/logpoc/out/out/cljs/core.cljs:1730:10)
at repl:1:34
at repl:9:3
at repl:14:4
at ContextifyScript.Script.runInThisContext (vm.js:44:33)
at Object.runInThisContext (vm.js:116:38)
at Domain.<anonymous> ([stdin]:50:34)
at Domain.run (domain.js:242:14)
Is this expected?it is source mapped no? I don’t think it supports showing the actual source excerpt but the stack looks mapped?
@thheller oh, well sorry, I tried before this and it was showing .js
files in there, then apparently I did something and now they are mapped
for the (lossy) records with no source-map-support
it was:
ClojureScript Node.js REPL server listening on 56975
Watch compilation log available at: out/watch.log
To quit, type: :cljs/quit
cljs.user=> (ffirst 1)
repl:13
throw e__7439__auto__;
^
Error: 1 is not ISeqable
at Object.cljs$core$seq [as seq] (/home/arichiardi/git/logpoc/out/out/cljs/core.js:4414:8)
at Object.cljs$core$first [as first] (/home/arichiardi/git/logpoc/out/out/cljs/core.js:4433:19)
at cljs$core$ffirst (/home/arichiardi/git/logpoc/out/out/cljs/core.js:5859:34)
at repl:1:96
at repl:9:3
at repl:14:4
at ContextifyScript.Script.runInThisContext (vm.js:44:33)
at Object.runInThisContext (vm.js:116:38)
at Domain.<anonymous> ([stdin]:50:34)
at Domain.run (domain.js:242:14)
when calling get
on a map in clojurescript 1.9.671 i get the following error and i'm stumped... any thoughts?
(get {:test "one"} :test)
Uncaught Error: No protocol method ICollection.-conj defined for type cljs.core/Keyword: :test
re :optimizations :none closure still needs to be called for the namespace stuff I think
What's a good way of dealing with eval timeout errors? Both in terms of debugging and catching
I have an expression that works in Javascript using web3 and BigNumber but hangs in Clojurescript when significant digits are above a certain limit
@oskarth what do you mean - there’s not really a way to deal with that in JavaScript either - do you mean just at the REPL?
Specifically, this works:
(.fromWei js/Web3.prototype 111122223333440000 "ether")
but this hangs: (.fromWei js/Web3.prototype 111122223333444000 "ether")
(treating numbers as strings causes the same behavior) whereas both equivalent forms work in a JS repl: web3.fromWei(111122223333440000, 'ether'
) web3.fromWei(111122223333444000, 'ether')
- trying to figure out why or deal with it somehow
@oskarth I’m confused since the CLJS isn’t equivalent to the JS, why aren’t you just writing the same thing?
web3.fromWei(111122223333444000, 'ether')
-> (.fromWei js/web3 111122223333444000 "ether")
by your initial example it would be js/Web3
(looks like there's a version mismatch, but can't quite figure out which version is being called and why they differ)
@oskarth Web3.js docs show that you should initialize web3
using Web3
constructor yourself:
(def web3 (js/Web3. provider?))
(.fromWei web3 111122223333444000, "ether")
@juhoteperi tried that, hangs
as far as I can tell they are just aliased, the implementation for this specific function hasn't changed. With one less significant digit it works fine
i’m curious wrt the new 1.9.854 changes in npm-deps and global exports for foreign libs - this doesn’t avoid the need of externs files, right?
in reagent/react/om, we provide "trees", the system then diffs then and modifies the dom; are there libraries for modifying the dom directly?
@qqq i wouldnt be so afraid of “unmaintained” libs.. in a lot of use cases that’s actually a good sign. the dom access api doesnt change all that frequently, for example. so the fact that domina is 2+ years unchanged means it hasn’t had any issues serving its purpose
it’s a strange feeling, I know. it took getting used to, coming from the js-ecosystem, where if something hasnt had changes in 2+ months feels like a “risky investment”
@lwhorton : yeah, with node.js, if the new package isn't somehow incompatible with your existing packages, something's wrong
i attribute this to the mature java ecosystem where people dont investigate a mvn dep and say “hey why hasnt com.goog.array been updated in 5 years?!“.. *and hopefully some of that is rubbing off on the js world
has anyone had any luck with spinning up a docker container with lein fighweel
&& lein garden auto
` concurrently running? Everything I’ve tried so far results in either a subprocess immediately failing or an out of memory error in the container.
is there a thin cljs wraper over google closure? I was just looking at my dependencies, and it seems like google closure provides alot of them
google closure is huge so there might be wrappers for some of it but probably not everything
I'm trying to simplify my cljs dependencies. Do I need weasel + piggieback if I don't need a cljs-repl ?
What’s a good, free service for hosting hobby projects in Clojure/Clojurescript?
heroku makes it pretty easy, or any free tier service that gives you enough RAM to run your project
cheers 🙂
you can make a standalone project with lein uberjar
and that should run on any host with a jvm and enough RAM
I’ll give Heroku another go.
I've built a test JS file using lein cljsbuild once
, and then I try to run it (using node
), but I get import errors since a dep is using ES6, so I run it through babel with es2015 presets and then try to run it again. Now, I just see Cannot use 'in' operator to search for 'doo' in undefined
@reefersleep "another" makes it sound like you've already tried Heroku. Did you have problems or something I can help with?
If I comment out the require for that ES6 code and thus avoid all the babel business, I end up getting __DEV__ is not defined
while running lein cljsbuild test
. Seems like I hit a wall either way.
@codefinger I didn't, I just never really put an effort into establishing a comfortable relationship with Heroku, and thought I'd ask around to see if there were other, possibly better options 🙂
I have managed to get something up and running.
Hah... two years ago. Damn! https://derpanet.herokuapp.com/
@reefersleep Google Cloud offers 300$ of free credits (usable over 12 months)
Heroku is great as a free option, and has amazing UX, but for hobby/non-profit projects that need more than their free dyno it’s prohibitively expensive. I am working on a couple of non-profit projects at the moment and I am experimenting with Kubernetes on Google Cloud. One of the neat things you can do is schedule some of your services on preemptible instances (which cost something like 30% of the full price, in exchange of the possiblity of them being shut down at any time)
I have heard of https://deis.com/workflow/ but haven’t tried it yet
There is also http://dokku.viewdocs.io/dokku/ ; it was too limited for my use-case but it might interest you
Recently I also stumbled upon https://hyper.sh/ (no idea how reliable they are though)
And https://zeit.co/now (which I found a bit dodgy but some people like it)
I've had a pretty bad experience with Clojure on GAE. From no Clojure tooling support to memory leaks in their infrastructure and dead end support for fixing existing issues.
I prefer to set up a deployment where nothing on the server even needs to know you have clojure in your deploy - making an uberjar, with a shim to some runner lib if needed
In theory, sure. In practice, it's very nice to have a lein plugin for your hosting service so you can easily deploy, troubleshoot, etc.
I never use lein on prod
(this is with years of full time clojure dev)
For my current project I have a CI job which builds an uberjar, packages it in a Docker image and pushes that to a repository
I don't think that changes anythying, @hmaurer, and I don't think anything I've said has implied such a CI pipeline isn't in place.
The point is, deploying, from wherever can be quite simple with a lein plugin. Like how Heroku does it.
@jeaye my rationale for not using any clojure tooling on my deploy target is to increase my choices and flexibility in deploy targets, it requires a bit of glue with CI and/or automated deploy tooling
but then all I need is a jvm, which is an easy bar to reach
I am a noob, but that’s one of the things I like the most about the JVM. I can just ship a jar to production and run java -jar ...
with a few options. No need to worry about installing the correct dependencies etc
@hmaurer With App Engine, a deployment requires building an uberwar, exploding it, replacing some files, and using a supplied GAE script to repackage it.
I know because the most up-to-date documentation on getting Clojure working with App Engine is right here: https://blog.jeaye.com/2016/08/23/clojure-app-engine/
ahem. more recent is https://github.com/migae/boot-gae/blob/master/README.adoc (author here). needs some work but the principles are sound
cheers @hmaurer 🙂
or in a Procfile
web: java -server $JVM_OPTS -jar target/myapp-standalone.jar host 0.0.0.0 port $PORT
-server
is optional and could even be provided in JVM_OPTS
instead
that way, your CI/CD can handle deploys instead of manual deploys
which I prefer
Recently ran into https://circleci.com/blog/deploying-clojure-applications-to-google-cloud/ which skips some of what you’ve done by leaning on Docker
boot-gae: boot gae/build -p gae/target gae/deploy
It'd be interesting to have one of the Google Closure compiler developers to give a talk at a clojure event.
@jakemcc Relying on App Engine Flexible forfeits all of the benefits of App Engine's "serverless," automatic environments. It also forfeits the support that Google would be required to give you for the stability of that environment, since now you're running your own.
Hi, as of today I'm no longer able to run lein uberjar for my app, it returns this error: NoSuchMethodError: com.google.common.base.CharMatcher.javaUpperCase()Lcom/google/common/base/CharMatcher; I gather this is a guava conflict (not sure why, didn't add any new dependencies). Any suggestions on how to troubleshoot this?